概述
在Java开发中定时器算是一个非常经典的小案例,在正式的项目中定时器也会经常使用。所以突然兴起想对定时器来一个总结分析,本人小白一个,请多多指教!
首先什么是Java定时器?
定时器相信大家都不陌生,平时使用定时器就像使用闹钟一样,我们可以在固定的时间做某件事,也可以在固定的时间段重复做某件事。在Java中为我们提供了Timer来实现定时任务,当然现在还有很多定时任务框架,比如说Spring、QuartZ、Linux Cron等等,而且性能也更加优越。但是我们想要深入的学习就必须先从最简单的开始。
1.Java定时器需要用到的类:
在JAVA中实现定时器功能要用的2个类是Timer,TimerTask
Timer类是用来履行任务的类,它接受1个TimerTask做参数
TimerTask是用来指定执行任务的类
2.Timer有两种履行任务的模式(schedule、scheduleAtFixedRate)
最经常使用的是schedule,它可以以两种方式履行任务:
1、在某个时间(Data),
2、在某个固定的时间以后(int delay)。
这两种方式都可以指定任务履行的频率
schedule和scheduleAtFixedRate的区分在于,如果指定开始履行的时间在当前系统运行时间之前,scheduleAtFixedRate会把已过去的时间也作为周期履行,而schedule不会把过去的时间算上。
案例代码如下:
package com.anyi.timer;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
/**
* @description:
* @author: anyi
* @date: 2021-03-05 09:42
**/
public class TimerTest1 {
public static void main(String[] args){
timer1();
timer2();
}
/**
* @Description: 设定2000毫秒后执行
*/
public static void timer1() {
Timer nTimer = new Timer();
nTimer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("执行指定的任务");
System.out.println("--起床--");
}
}, 2000);
}
/**
* @Description: 延迟5000毫秒,每1000毫秒执行一次
*/
public static void timer2(){
Timer nTimer = new Timer();
nTimer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("执行指定任务");
System.out.println("--吃饭--");
}
}, 5000, 1000);
}
//延迟5000毫秒,每1000毫秒执行一次
public static void timer3(){
Timer nTimer = new Timer();
nTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println("执行指定任务");
System.out.println("背英语单词");
}
}, 5000, 1000);
}
/**
* 设置17:56执行任务
* java.util.Timer.scheduleAtFixedRate(TimerTask task, Date firstTime, long period)
*/
public static void timer4(){
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 17);
calendar.set(Calendar.MINUTE, 56);
calendar.set(Calendar.SECOND, 0);
Date time = calendar.getTime();
Timer nTimer = new Timer();
nTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println("执行指定任务");
System.out.println("码代码");
}
}, time,1000*24*60*60);// 这里设定将延时每天固定执行
}
}
3.Timer的缺点及改进方法
Timer不支持并发,Timer不支持多线程,一个Timer只开启一个线程。全部挂在Timer下的任务都是单线程的,任务仅仅能串行运行。假设当中一个任务运行时间过长。会影响到其它任务的运行,然后就可能会有各种接踵而来的问题。如果重开一个Timer?难道要为全部的耗时的Task都单开一个Timer。显然是不太可能。这样就太乱了。
Timer的线程不捕获异常。TimerTask假设抛出异常,那么Timer唯一的进程就会挂掉,这样挂在Timer下的全部任务都会无法继续运行
改进方法:
为了弥补Timer的缺陷,jdk1.5中引入了并发包。这里面提供的ScheduledExecutorService。详细实现类是:ScheduledThreadPoolExecutor。ScheduledThreadPoolExecutor支持多线程。同一时候在线程中对异常进行了捕获。所以是Timer的完美替换者。
这种情况,我们只需要按照阿里规约里面给的建议。
多线程并行处理定时任务时,Timer运行多个TimeTask时,只要其中之一没有捕获抛出的异常,其它任务会自动终止运行,使用ScheduledExecutorService则没有这个问题。
————————————————
摘自:
原文链接:https://blog.csdn.net/u013636987/article/details/102671841
4.使用ScheduledExecutorService替代Timer
(1)注意事项(避坑!)
其中BasicThreadFactory类来自:org.apache.commons.lang3.concurrent.BasicThreadFactory,需要导入相应的第三方jar包,否则会报Cannot resolve symbol ‘BasicThreadFactory’
这里使用maven的方式导入:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8</version>
</dependency>
(2)根据规约的提示我们写一个简单的demo (JDK1.8+)
@Component
public class ScheduledThreadPoolTaskTimer {
@PostConstruct
public void init(){
ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1,
new BasicThreadFactory.Builder().namingPattern("task-timer-pool-%d").daemon(true).build());
executorService.scheduleAtFixedRate(this::performingTasks,0,1000, TimeUnit.MILLISECONDS);
}
public void performingTasks(){
System.out.println("Are you ok?"+System.currentTimeMillis());
}
}
这里我们使用了BasicThreadFactory去创建线程,也就是采用线程池的方式。scheduleAtFixedRate方法参数如下
@param command 要执行的任务
@param initialDelay 延迟首次执行的时间
@param period 连续执行之间的时间间隔
@param unit initialDelay和period参数的时间单位
————————————————
案例代码参考来自
原文链接:https://blog.csdn.net/qq_36428889/article/details/103010460
最后
以上就是单薄洋葱为你收集整理的【Java案例实践】Java定时器最全讲解(包括多线程定时任务)1.Java定时器需要用到的类:2.Timer有两种履行任务的模式(schedule、scheduleAtFixedRate)3.Timer的缺点及改进方法4.使用ScheduledExecutorService替代Timer的全部内容,希望文章能够帮你解决【Java案例实践】Java定时器最全讲解(包括多线程定时任务)1.Java定时器需要用到的类:2.Timer有两种履行任务的模式(schedule、scheduleAtFixedRate)3.Timer的缺点及改进方法4.使用ScheduledExecutorService替代Timer所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复