定时任务是在指定时间执行程序,或周期性执行计划任务。
Java中实现定时任务的方法有很多,主要JDK自带的一些方法以及开源程序如Qurtz。
1.Timer和TimerTask
Timer只是充当了一个执行者的角色,真正的任务逻辑是通过一个叫做TimerTask的抽象类完成的,TimerTask也是java.util包下面的类,
它是一个实现了Runnable接口的抽象类,包含一个抽象方法run( )方法,需要我们自己去提供具体的业务实现。
Timer 的优点在于简单易用,但由于所有任务都是由同一个线程来调度,
因此所有任务都是串行执行的,同一时间只能有一个任务在执行,前一个任务的延迟或异常都将会影响到之后的任务。
示例代码:
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
|
public
class
TimerTest {
//被执行的任务必须继承TimerTask,并且实现run方法
static
class
MyTimerTask1
extends
TimerTask {
public
void
run() {
System.out.println(
"执行当前线程"
+Thread.currentThread().getName());
}
}
/**
* Timer线程不会捕获异常,所以TimerTask抛出的未检查的异常会终止timer线程。
* 如果Timer线程中存在多个计划任务,其中一个计划任务抛出未检查的异常,则会引起整个Timer线程结束,从而导致其他计划任务无法得到继续执行。
* Timer线程时基于绝对时间,因此计划任务对系统的时间的改变是敏感的。
* Timer是单线程,如果某个任务很耗时,可能会影响其他计划任务的执行。
* @param args
* @throws ParseException
* @throws InterruptedException
*/
public
static
void
main(String[] args)
throws
ParseException, InterruptedException {
Timer timer =
new
Timer();
/**
* scheduleAtFixedRate方式
* 设定两秒后执行任务
*/
timer.scheduleAtFixedRate(
new
MyTimerTask1(),
2000
,
1000
);
/**
* schedule添加Date参数
* 设定任务在执行时间执行
*/
// SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
// Date time = dateFormatter.parse("2016/03/28 14:40:00");
// timer.schedule(new MyTimerTask1(), time);
//启动MyTimerTask1线程后,主线程休眠五秒钟,给MyTimerTask1五秒的执行时间
Thread.sleep(
5000
);
//终止Timer线程
timer.cancel();
}
}
|
JDK 5.0以后推荐使用ScheduledThreadPoolExecutor。关于Timer简单了解即可。
2.ScheduledThreadPoolExecutor
ScheduledThreadPoolExecutor属于Executor Framework,
它除了能处理异常外,还可以以多线程方式执行定时任务。
Timer类是通过单线程来执行所有的TimerTask任务的,如果一个任务的执行过程非常耗时,将会导致其他任务的时效性出现问题。
而 ScheduledThreadPoolExecutor是基于线程池的多线程执行任务,不会存在这样的问题。
通过一个实例学习:
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
|
public
class
ScheduledThreadPoolExecutorTest {
public
static
void
main(String[] args) {
//获得实例,并且设置它的容量为5个
ScheduledThreadPoolExecutor sExecutor=
new
ScheduledThreadPoolExecutor(
5
);
MyTask task =
new
MyTask();
//隔2秒后开始执行任务,并且在上一次任务开始后隔一秒再执行一次
// sExecutor.scheduleWithFixedDelay(task, 2, 1, TimeUnit.SECONDS);
//隔6秒后执行一次,但只会执行一次
sExecutor.schedule(task,
6
, TimeUnit.SECONDS);
/**
* 和Timer类似,也可以直接在任务的run()方法中调用调度方法停止
* 这个方法会平滑的关闭调度器,等待所有任务结束
*/
sExecutor.shutdown();
}
static
class
MyTask
implements
Runnable{
@Override
public
void
run() {
System.out.println(
"当前执行的线程"
+Thread.currentThread().getName());
}
}
}
|
3.使用Qurtz
Qurtz的使用非常简单,作为解决方案支持更多的触发机制。
本文转自邴越博客园博客,原文链接:http://www.cnblogs.com/binyue/p/5328921.html,如需转载请自行联系原作者