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
|
package
com.journaldev.threads;
import
java.util.Date;
public
class WorkerThread implements
Runnable{
private
String command;
public
WorkerThread(String s){
this .command=s;
}
@Override
public
void run() {
System.out.println(Thread.currentThread().getName()+ " Start. Time = " + new
Date());
processCommand();
System.out.println(Thread.currentThread().getName()+ " End. Time = " + new
Date());
}
private
void processCommand() {
try
{
Thread.sleep( 5000 );
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public
String toString(){
return
this .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
|
package
com.journaldev.threads;
import
java.util.Date;
import
java.util.concurrent.Executors;
import
java.util.concurrent.ScheduledExecutorService;
import
java.util.concurrent.TimeUnit;
public
class ScheduledThreadPool {
public
static void
main(String[] args) throws
InterruptedException {
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool( 5 );
System.out.println( "Current Time = " + new
Date());
for ( int
i= 0 ; i< 3 ; i++){
Thread.sleep( 1000 );
WorkerThread worker =
new WorkerThread( "do heavy processing" );
scheduledThreadPool.schedule(worker,
10 , TimeUnit.SECONDS);
}
Thread.sleep( 30000 );
scheduledThreadPool.shutdown();
while (!scheduledThreadPool.isTerminated()){
}
System.out.println( "Finished all threads" );
}
}
|
运行上面的程序,可以得到下面的输出,由此可以确认任务在10s后才执行。
1
2
3
4
5
6
7
8
|
Current Time = Tue Oct 29 15:10:03 IST 2013
pool-1-thread-1 Start. Time = Tue Oct 29 15:10:14 IST 2013
pool-1-thread-2 Start. Time = Tue Oct 29 15:10:15 IST 2013
pool-1-thread-3 Start. Time = Tue Oct 29 15:10:16 IST 2013
pool-1-thread-1 End. Time = Tue Oct 29 15:10:19 IST 2013
pool-1-thread-2 End. Time = Tue Oct 29 15:10:20 IST 2013
pool-1-thread-3 End. Time = Tue Oct 29 15:10:21 IST 2013
Finished 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
( int i =
0 ; i < 3 ; i++) {
Thread.sleep( 1000 );
WorkerThread worker =
new WorkerThread( "do heavy processing" );
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 2013
pool-1-thread-1 Start. Time = Tue Oct 29 16:10:01 IST 2013
pool-1-thread-2 Start. Time = Tue Oct 29 16:10:02 IST 2013
pool-1-thread-3 Start. Time = Tue Oct 29 16:10:03 IST 2013
pool-1-thread-1 End. Time = Tue Oct 29 16:10:06 IST 2013
pool-1-thread-2 End. Time = Tue Oct 29 16:10:07 IST 2013
pool-1-thread-3 End. Time = Tue Oct 29 16:10:08 IST 2013
pool-1-thread-1 Start. Time = Tue Oct 29 16:10:11 IST 2013
pool-1-thread-4 Start. Time = Tue Oct 29 16:10:12 IST 2013
|
scheduleWithFixedDelay(Runnable command,long initialDelay,long delay,TimeUnit unit)
该方法可被用于延迟周期性执行任务,delaytime是线程停止执行到下一次开始执行之间的延迟时间,假设有下面的代码
1
2
3
4
5
6
|
for
( int i =
0 ; i < 3 ; i++) {
Thread.sleep( 1000 );
WorkerThread worker =
new WorkerThread( "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 2013
pool-1-thread-1 Start. Time = Tue Oct 29 16:14:14 IST 2013
pool-1-thread-2 Start. Time = Tue Oct 29 16:14:15 IST 2013
pool-1-thread-3 Start. Time = Tue Oct 29 16:14:16 IST 2013
pool-1-thread-1 End. Time = Tue Oct 29 16:14:19 IST 2013
pool-1-thread-2 End. Time = Tue Oct 29 16:14:20 IST 2013
pool-1-thread-1 Start. Time = Tue Oct 29 16:14:20 IST 2013
pool-1-thread-3 End. Time = Tue Oct 29 16:14:21 IST 2013
pool-1-thread-4 Start. Time = Tue Oct 29 16:14:21 IST 2013
|
分享到:
相关推荐
该demo只是实现定时监听、周期性执行任务的功能,而邮件发送、文件删除等自定义功能需要自行添加上去,只需在run方法下修改邮件发送、文件删除等功能即可;
java定时任务,每天定时执行任务,每天到这个时间点都会执行
java每天实现定点执行任务java每天实现定点执行任务java每天实现定点执行任务java每天实现定点执行任务java每天实现定点执行任务java每天实现定点执行任务java每天实现定点执行任务
java每天实现定点执行任务java每天实现定点执行任务java每天实现定点执行任务java每天实现定点执行任务
java定时任务,每天定时执行任务,包括这个例子的全部代码。
java 定时执行任务
Java调用控制台python命令(含传递参数)执行DataX的job任务,mysql向odps同步数据。
JAVA项目服务器启动时自启动指定的Servlet,并定时执行任务。 配置关键在web.xml和servlet文件中的init操作
由于个人需要使用,结合API和网友们的相关介绍,自己写了一个小小的demo可以通过java实现一个小程序语句的延迟执行,希望给需要的人提供帮助吧。
Java定时任务是Java提供的一种在指定时间执行任务的功能,它可以帮助开发者实现一些周期性或者延迟的任务。 Java定时任务的分类 Java定时任务主要分为两种类型,一种是单次定时任务,即只执行一次的任务;另一种是...
介绍了Java定时执行任务,给出了如何使用ServletContextListener实现定时运行java某个方法的例子,简单易用。
java定时执行多任务和quartz定时执行多任务
Quartz--JAVA定时任务\Java应用:Java调度任务和Spring Quartz (1)
java 执行sql脚本 例子java 执行sql脚本 例子java 执行sql脚本 例子java 执行sql脚本 例子java 执行sql脚本 例子java 执行sql脚本 例子java 执行sql脚本 例子java 执行sql脚本 例子java 执行sql脚本 例子java 执行...
主要介绍了Java如何处理延迟任务过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
本工具包主要是基于JAVA的底层时间类的处理周期时间的工具包,主要用于处理并得到周期性提醒的时间,比如说您想要在每天8:10、每月1号8:20、每周三8:30、每10分钟、每3小时、每季度第一个月1号8:10等等处理一项...
在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等。 对于这样的操作最方便、高效的实现方式就是使用java.util.Timer工具类。
spring定时器代码。解决多次执行问题。包含quartz-all.jar包。 说明很详细。希望能帮上哪位朋友。
在实际项目应用中经常会用到定时任务,可以通过quartz和spring的简单配置即可完成,但如果要改变任务的执行时间、频率,废弃任务等就需要改变配置甚至代码需要重启服务器,这里介绍一下如何通过quartz与spring的组合...
实现了一个简单的任务调度器,可以安排任务在指定的延迟时间后执行。 使用Java的ExecutorService类创建了一个固定大小的线程池,并将任务安排到线程池中执行。 通过调用`scheduleTask()`方法,可以指定要执行的任务...