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自动执行任务是指在WEB工程中实现自动执行任务的功能,通过使用Servlet上下文相关的侦听器和Java定时器来实现。下面是相关知识点的详细解释: 1. Servlet上下文相关的侦听器 在WEB工程中,...
在 Java 中,ScheduledThreadPoolExecutor 是一个线程池执行器,用于执行延迟任务。它使用DelayedWorkQueue来实现延迟的效果。下面是 ScheduledThreadPoolExecutor 的实现细节: 首先,ScheduledThreadPoolExecutor...
java定时任务,每天定时执行任务,包括这个例子的全部代码。
java 定时执行任务
JAVA项目服务器启动时自启动指定的Servlet,并定时执行任务。 配置关键在web.xml和servlet文件中的init操作
Java调用控制台python命令(含传递参数)执行DataX的job任务,mysql向odps同步数据。
由于个人需要使用,结合API和网友们的相关介绍,自己写了一个小小的demo可以通过java实现一个小程序语句的延迟执行,希望给需要的人提供帮助吧。
Java定时任务是Java提供的一种在指定时间执行任务的功能,它可以帮助开发者实现一些周期性或者延迟的任务。 Java定时任务的分类 Java定时任务主要分为两种类型,一种是单次定时任务,即只执行一次的任务;另一种是...
介绍了Java定时执行任务,给出了如何使用ServletContextListener实现定时运行java某个方法的例子,简单易用。
java定时执行多任务和quartz定时执行多任务
Java 定时任务 Java 定时任务是指在 Java 应用程序中使用 Timer 和 TimerTask 来执行定时任务的机制。...Java 定时任务提供了一种灵活和可靠的方式来执行定时任务,从而提高应用程序的效率和可靠性。
java 执行sql脚本 例子java 执行sql脚本 例子java 执行sql脚本 例子java 执行sql脚本 例子java 执行sql脚本 例子java 执行sql脚本 例子java 执行sql脚本 例子java 执行sql脚本 例子java 执行sql脚本 例子java 执行...
主要介绍了Java如何处理延迟任务过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
在 Java 中,函数的调用过程可以是同步的或异步的,同步调用是指函数的执行过程是阻塞的,而异步调用是指函数的执行过程是非阻塞的。 函数的重载是指在一个类中可以存在多个同名函数,只要它们的参数个数或类型不同...
本工具包主要是基于JAVA的底层时间类的处理周期时间的工具包,主要用于处理并得到周期性提醒的时间,比如说您想要在每天8:10、每月1号8:20、每周三8:30、每10分钟、每3小时、每季度第一个月1号8:10等等处理一项...
在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等。 对于这样的操作最方便、高效的实现方式就是使用java.util.Timer工具类。