Java ScheduledThreadPoolExecutor延迟或周期性执行任务
ImportNew注: 本文由新浪微博:@小飞侠_thor 投稿至ImportNew。感谢@小飞侠_thor ! 如果你希望分享好的原创文章或者译文,欢迎投稿到ImportNew。
Java提供的Time类可以周期性地或者延期执行任务,但是有时我们需要并行执行同样的任务,这个时候如果创建多个Time对象会给系统带来负担,解决办法是将定时任务放到线程池中执行。
Java的ScheduledThreadPoolExecutor类实现了ScheduledExecutorService接口中定义的以不同方法执行任务的方法。
之前,我写过一篇关于Java ThreadPoolExecutor的文章中使用了Executors创建线程池。Executors类也提供了工厂方法创建ScheduledThreadPoolExecutor,并且可以设置线程池中的线程。
假设有下面简单的Runnable类
WorkerThread.java:
|
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
|
packagecom.journaldev.threads;importjava.util.Date;publicclass
WorkerThread implementsRunnable{privateString
command; publicWorkerThread(String
s){ this.command=s; } @Override publicvoid
run() { System.out.println(Thread.currentThread().getName()+"
Start. Time = "+newDate()); processCommand(); System.out.println(Thread.currentThread().getName()+"
End. Time = "+newDate()); } privatevoid
processCommand() { try{ Thread.sleep(5000); }catch(InterruptedException
e) { e.printStackTrace(); } } @Override publicString
toString(){ returnthis.command; }} |
下面的例子中worker线程将被延期10s执行上面的Rnnable类大约花费5s执行任务
ScheduledThreadPool.java:
|
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
|
packagecom.journaldev.threads;importjava.util.Date;importjava.util.concurrent.Executors;importjava.util.concurrent.ScheduledExecutorService;importjava.util.concurrent.TimeUnit;publicclass
ScheduledThreadPool { publicstatic
void
main(String[] args) throwsInterruptedException
{ ScheduledExecutorService
scheduledThreadPool = Executors.newScheduledThreadPool(5); //schedule
to run after sometime System.out.println("Current
Time = "+newDate()); for(inti=0;
i<3;
i++){ Thread.sleep(1000); WorkerThread
worker = newWorkerThread("do
heavy processing"); scheduledThreadPool.schedule(worker,10,
TimeUnit.SECONDS); } //add
some delay to let some threads spawn by scheduler Thread.sleep(30000); scheduledThreadPool.shutdown(); while(!scheduledThreadPool.isTerminated()){ //wait
for all tasks to finish } System.out.println("Finished
all threads"); }} |
运行上面的程序,可以得到下面的输出,由此可以确认任务在10s后才执行。
|
1
2
3
4
5
6
7
8
|
Current
Time = Tue Oct 29 15:10:03 IST 2013pool-1-thread-1
Start. Time = Tue Oct 29 15:10:14 IST 2013pool-1-thread-2
Start. Time = Tue Oct 29 15:10:15 IST 2013pool-1-thread-3
Start. Time = Tue Oct 29 15:10:16 IST 2013pool-1-thread-1
End. Time = Tue Oct 29 15:10:19 IST 2013pool-1-thread-2
End. Time = Tue Oct 29 15:10:20 IST 2013pool-1-thread-3
End. Time = Tue Oct 29 15:10:21 IST 2013Finished
all threads |
注意到所有的schedule方法都返回了ScheduledFuture实例,可以用于获取线程状态信息和延迟时间。ScheduledFuture接口继承Future接口,更多信息见Java Callable Future Example.
在ScheduledExecutorService中至少有2个方法可用于周期性执行任务。
scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnit unit)
我们可以使用该方法延迟执行任务,设置任务的执行周期。时间周期从线程池中首先开始执行的线程算起,所以假设period为1s,线程执行了5s,那么下一个线程在第一个线程运行完后会很快被执行。
比如下面的代码
|
1
2
3
4
5
6
|
for(inti
= 0;
i < 3;
i++) { Thread.sleep(1000); WorkerThread
worker = newWorkerThread("do
heavy processing"); //
schedule task to execute at fixed rate scheduledThreadPool.scheduleAtFixedRate(worker,0,10, TimeUnit.SECONDS); |
|
1
2
3
4
5
6
7
8
9
|
Current
Time = Tue Oct 29 16:10:00 IST 2013pool-1-thread-1
Start. Time = Tue Oct 29 16:10:01 IST 2013pool-1-thread-2
Start. Time = Tue Oct 29 16:10:02 IST 2013pool-1-thread-3
Start. Time = Tue Oct 29 16:10:03 IST 2013pool-1-thread-1
End. Time = Tue Oct 29 16:10:06 IST 2013pool-1-thread-2
End. Time = Tue Oct 29 16:10:07 IST 2013pool-1-thread-3
End. Time = Tue Oct 29 16:10:08 IST 2013pool-1-thread-1
Start. Time = Tue Oct 29 16:10:11 IST 2013pool-1-thread-4
Start. Time = Tue Oct 29 16:10:12 IST 2013 |
|
1
2
3
4
5
6
|
for(inti
= 0;
i < 3;
i++) { Thread.sleep(1000); WorkerThread
worker = newWorkerThread("do
heavy processing"); scheduledThreadPool.scheduleWithFixedDelay(worker,0,1, TimeUnit.SECONDS);} |
|
1
2
3
4
5
6
7
8
9
|
Current
Time = Tue Oct 29 16:14:13 IST 2013pool-1-thread-1
Start. Time = Tue Oct 29 16:14:14 IST 2013pool-1-thread-2
Start. Time = Tue Oct 29 16:14:15 IST 2013pool-1-thread-3
Start. Time = Tue Oct 29 16:14:16 IST 2013pool-1-thread-1
End. Time = Tue Oct 29 16:14:19 IST 2013pool-1-thread-2
End. Time = Tue Oct 29 16:14:20 IST 2013pool-1-thread-1
Start. Time = Tue Oct 29 16:14:20 IST 2013pool-1-thread-3
End. Time = Tue Oct 29 16:14:21 IST 2013pool-1-thread-4
Start. Time = Tue Oct 29 16:14:21 IST 2013 |
如果你喜欢本文, 请长按二维码,关注公众号 分布式编程.
作者:分布式编程
出处:https://zthinker.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
浙公网安备 33010602011771号