6.在执行器中延时执行任务
前面两篇博客都是创建执行器之后启动任务会马上执行,这里如果不想让任务马上被执行,
而是想让任务在过一段时间后才被执行,或者任务能够被周期性地执行。可以使用执行器框架提供的
ScheduledThreadPoolExecutor类
这里推荐利用Executors工厂类来创建,定时执行器。使用Executors工厂的newScheduledThreadPool()方法创建该实例对象。方法中的一个参数就是线程池中拥有的线程数量,。
在定时起中等待一段给定的时间后执行一个任务,需要使用schedule()方法,这个方法接收如下参数
1.即将执行的任务
2.任务执行前所要等待的时间。
3.等待时间的单位,由TimeUnit类的一个常量来指定。
备注:
1.如果想在一个给定的时间点来定时执行任务,那就需要计算这个给定时间点和当前时间的差异值,然后用这个差异值作为任务的延迟值。
2.也可以使用Runnable接口来实现任务,因为ScheduledThreadPoolExecutor类的Schedule()方法可以同时接受这两种类型的任务。
3.在调用shutdown方法而仍有待处理的任务需要执行时,可以配置ScheduledThreadPoolExecutor的行为。默认的行为是不论执行器是否结束,待处理的任务都将被执行。
但是通过调用该类的setExecuteExistingDelayedTasksAfterShutdownPolicy方法则可以改变这个行为。传递false参数给这个方法,执行shutdown()方法后待处理的任务将不再执行。
2.测试类
7.在执行器中周期性执行任务
有时候任务需要周期性的执行,就需要使用ScheduledThreadPoolExecutor类来执行周期性的任务。
先需要创建一个ScheduledExecutorService对象。同创建执行器一样,在java中推荐使用Executors工厂类来创建ScheduledExecutorService对象。
Executors类就是执行器对象的工厂
。在本范例中使用scheduledAtFixedRate()方法发送任务。这个方法接收4个参数,分别为将被周期性执行的任务,任务第一次执行后的延时时间,
两次执行的时间周期,以及第二第三个参数的单位。
需要注意的是,两次执行之间的周期是指任务在两次执行开始时的时间间隔。
scheduleAtFixedRate()方法返回一个ScheduledFuture对象,ScheduleFuture接口扩展了Future接口,带有定时任务相关的操作方法。ScheduledFuture是一个
泛型参数化的接口。在该范例中,任务是Runnable对象,并没有泛型参数化,必须通过?符号作为参数来泛型化。
可以使用ScheduledFuture接口中的一个方法,getDelay()方法返回任务到下一次执行时锁要等待的剩余时间。这个方法接收一个TimeUnit常量作为时间单位。
前面两篇博客都是创建执行器之后启动任务会马上执行,这里如果不想让任务马上被执行,
而是想让任务在过一段时间后才被执行,或者任务能够被周期性地执行。可以使用执行器框架提供的
ScheduledThreadPoolExecutor类
这里推荐利用Executors工厂类来创建,定时执行器。使用Executors工厂的newScheduledThreadPool()方法创建该实例对象。方法中的一个参数就是线程池中拥有的线程数量,。
在定时起中等待一段给定的时间后执行一个任务,需要使用schedule()方法,这个方法接收如下参数
1.即将执行的任务
2.任务执行前所要等待的时间。
3.等待时间的单位,由TimeUnit类的一个常量来指定。
备注:
1.如果想在一个给定的时间点来定时执行任务,那就需要计算这个给定时间点和当前时间的差异值,然后用这个差异值作为任务的延迟值。
2.也可以使用Runnable接口来实现任务,因为ScheduledThreadPoolExecutor类的Schedule()方法可以同时接受这两种类型的任务。
3.在调用shutdown方法而仍有待处理的任务需要执行时,可以配置ScheduledThreadPoolExecutor的行为。默认的行为是不论执行器是否结束,待处理的任务都将被执行。
但是通过调用该类的setExecuteExistingDelayedTasksAfterShutdownPolicy方法则可以改变这个行为。传递false参数给这个方法,执行shutdown()方法后待处理的任务将不再执行。
实例代码
/**
*
* @author fcs
* @date 2015-5-5
* 描述:在执行器中延迟执行任务
* 说明:
*/
public class Task implements Callable<String> {
private String name;
public Task(String name) {
this.name = name;
}
@Override
public String call() throws Exception {
System.out.printf("%s: Starting at: %s\n",name,new Date());
return "return hello world";
}
}
2.测试类
/**
*
* @author fcs
* @date 2015-5-5
* 描述:ScheduledThreadPoolExecutor:可以让任务在过一段时间后才被执行,或者任务能够被周期性的执行。
*/
public class Main {
public static void main(String[] args) {
ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor)Executors.newScheduledThreadPool(1);
System.out.printf("Main: Starting at: %s\n",new Date());
for(int i =0;i< 5;i++){
Task task = new Task("Task"+i);
//通过该方法启动这些任务
executor.schedule(task, i+1, TimeUnit.SECONDS);
}
executor.shutdown();
try {
//通过该方法等待所有任务完成
executor.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Main: Ends at: %s\n",new Date());
}
}
7.在执行器中周期性执行任务
有时候任务需要周期性的执行,就需要使用ScheduledThreadPoolExecutor类来执行周期性的任务。
先需要创建一个ScheduledExecutorService对象。同创建执行器一样,在java中推荐使用Executors工厂类来创建ScheduledExecutorService对象。
Executors类就是执行器对象的工厂
。在本范例中使用scheduledAtFixedRate()方法发送任务。这个方法接收4个参数,分别为将被周期性执行的任务,任务第一次执行后的延时时间,
两次执行的时间周期,以及第二第三个参数的单位。
需要注意的是,两次执行之间的周期是指任务在两次执行开始时的时间间隔。
scheduleAtFixedRate()方法返回一个ScheduledFuture对象,ScheduleFuture接口扩展了Future接口,带有定时任务相关的操作方法。ScheduledFuture是一个
泛型参数化的接口。在该范例中,任务是Runnable对象,并没有泛型参数化,必须通过?符号作为参数来泛型化。
可以使用ScheduledFuture接口中的一个方法,getDelay()方法返回任务到下一次执行时锁要等待的剩余时间。这个方法接收一个TimeUnit常量作为时间单位。
实例代码:
1
/**
*
* @author fcs
* @date 2015-5-6
* 描述:在执行器中周期性执行任务
* 说明:使用ScheduledThreadPoolExecutor类来周期性的执行任务
*/
public class Task implements Runnable{
private String name;
public Task(String name) {
this.name = name;
}
@Override
public void run() {
System.out.printf("%s:Starting at: %s\n",name,new Date());
}
}
2.Main测试类
public class Main {
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
System.out.printf("Main: Starting at: %s\n",new Date());
Task task = new Task("Task");
/**
* 参数说明
* 1.要执行的任务
* 2.首次执行的延迟时间
* 3.连续执行之间的周期
* 4. 2,3时间参数的单位
*/
ScheduledFuture<?> result = executor.scheduleAtFixedRate(task, 1, 2,TimeUnit.SECONDS);
for(int i =0 ;i< 10;i++){
System.out.printf("Main: Delay: %d\n",result.getDelay(TimeUnit.MILLISECONDS));
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
executor.shutdown();
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Main: Finished at: %s\n",new Date());
}
}