所谓定时任务有两个核心要素:
1、任务开始时间:可以指定任务在将来某个时间点运行,或者指定任务从现在开始延迟一个时间段运行
2、任务执行周期:可以指定该任务每间隔多久执行一次
Java实现定时任务有三种方法:
一、利用Thread及Sleep实现,通过while循环让其不停运行
public class TimerTaskDemo {
public static void main(String[] args) {
Runnable runable=new Runnable() {
@Override
public void run() {
System.out.println("子线程执行任务,当前时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
}
};
try {
System.out.println("主线程启动子线程时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
scheduleThread(5L,3,runable);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/***
*
* @param duration 指定什么时间后运行 单位:秒
* @param timeInterval 每次运行间隔时间 单位:秒
* @param runnable 待运行的Runable对象
* @throws InterruptedException
*/
static void scheduleThread(Long duration,Integer timeInterval,Runnable runnable) throws InterruptedException{
/*阻塞等待*/
TimeUnit.SECONDS.sleep(duration);
//Thread.sleep(duration*1000);
final Runnable interiorRun=runnable;
final Integer interiorTimeInterval=timeInterval;
/*运行*/
new Thread(new Runnable() {
@Override
public void run() {
while(true){
/*执行方法*/
interiorRun.run();
try {
/*任务执行间隔*/
TimeUnit.SECONDS.sleep(interiorTimeInterval);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
二、利用Timer和TimerTask
先说下两者关联和区别:
1、Timer是调度者,可以安排任务执行计划,包括:任务时间、执行频率,也可停止任务。
2、TimerTask是任务。Timer类可以调度TimerTask任务,TimerTask则通过在run()方法里实现具体任务。TimerTask也可停止自身任务。
3、一个Timer可以调度多个TimerTask。
4、Timer是单线程的:Timer构造函数调用时会创建了一个新线程,所有TimerTask都是依靠这个新的线程执行。默认线程名:Timer-0
模拟一个进度条:
public class TimerTaskDemo {
public static void main(String[] args) {
Timer timer = new Timer();
MyTimerTask mytask=new MyTimerTask();
timer.schedule(mytask, 0, 300);
try {
TimeUnit.SECONDS.sleep(10);
/*10秒后停止任务*/
mytask.cancel();//停止运行指定的TimerTask
//timer.cancel();//停止运行timer上所有TimerTask
System.out.print("100%");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
static class MyTimerTask extends java.util.TimerTask {
public void run() {
System.out.print(">");
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
三、ScheduledExecutorService
Java SE 5后在JUC中提供了一个工具类:ScheduledExecutorService,这是最理想的定时任务实现方式。
相比于上两种方法,它有以下好处:
1、相比于Timer的单线程,它是通过线程池的方式来执行任务的。
2、可以很灵活的去设定第一次执行任务delay时间。
3、方法中提供TimeUnit,可设定时间单位。
public class TimerTaskDemo {
public static void main(String[] args) {
ScheduledExecutorService ses=Executors.newScheduledThreadPool(2);
ses.scheduleAtFixedRate(new MyTimerTask(), 2, 1, TimeUnit.SECONDS);
ses.scheduleAtFixedRate(new MyTimerTask(), 1, 1, TimeUnit.SECONDS);
try {
TimeUnit.SECONDS.sleep(10);
/*10秒后停止任务*/
ses.shutdown();//停止运行线程池上的所有runable。
System.out.print("--运行10秒停止--");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/*TimerTask实现Runable接口*/
static class MyTimerTask extends java.util.TimerTask {
public void run() {
System.out.println(Thread.currentThread().getName()+":"+ Calendar.getInstance().get(Calendar.SECOND));
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
输出结果,可以看到开启了两个线程运行任务。(pool-1-thread-1及pool-1-thread-2)
转自 https://blog.csdn.net/soonfly/article/details/70917204