java线程延迟执行_线程执行者(七)执行者延迟运行一个任务

声明:本文是《 Java 7 Concurrency Cookbook》的第四章,作者: Javier Fernández González     译者:许巧辉     校对:方腾飞,叶磊

执行者延迟运行一个任务

执行者框架提供ThreadPoolExecutor类,使用池中的线程来执行Callable和Runnable任务,这样可以避免所有线程的创建操作。当你提交一个任务给执行者,会根据执行者的配置尽快执行它。在有些使用情况下,当你对尽快执行任务不感觉兴趣。你可能想要在一段时间之后执行任务或周期性地执行任务。基于这些目的,执行者框架提供 ScheduledThreadPoolExecutor类。

在这个指南中,你将学习如何创建ScheduledThreadPoolExecutor和如何使用它安排任务在指定的时间后执行。

准备工作…

这个指南的例子使用Eclipse IDE实现。如果你使用Eclipse或其他IDE,如NetBeans,打开它并创建一个新的Java项目。

如何做…

按以下步骤来实现的这个例子:

1.创建Task类,实现Callable接口,参数化为String类型。

public class Task implements Callable {

2.声明一个私有的、类型为String、名为name的属性,用来存储任务的名称。

private String name;

3.实现Task类的构造器,初始化name属性。

public Task(String name) {

this.name=name;

}

4.实现call()方法,写入实际日期到控制台,返回一个文本,如:Hello, world。

public String call() throws Exception {

System.out.printf("%s: Starting at : %s\n",name,new Date());

return "Hello, world";

}

5.实现示例的主类,创建Main类,实现main()方法。

public class Main {

public static void main(String[] args) {

6.使用Executors类的newScheduledThreadPool()方法,创建ScheduledThreadPoolExecutor类的一个执行者。传入参数1。

ScheduledThreadPoolExecutor executor=(ScheduledThreadPoolExecutor)Executors.newScheduledThreadPool(1);

7.使用ScheduledThreadPoolExecutor实例的schedule()方法,初始化和开始一些任务(本例中5个任务)。

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);

}

8.使用shutdown()方法关闭执行者。

executor.shutdown();

9.使用执行者的awaitTermination()方法,等待所有任务完成。

try {

executor.awaitTermination(1, TimeUnit.DAYS);

} catch (InterruptedException e) {

e.printStackTrace();

}

10.写入一条信息表明程序结束时间。

System.out.printf("Main: Ends at: %s\n",new Date());

它是如何工作的…

在这个示例中,关键的一点是Main类和ScheduledThreadPoolExecutor的管理。正如使用ThreadPoolExecutor类创建预定的执行者,Java建议利用Executors类。在本例中,你使用newScheduledThreadPool()方法。你用1作为参数传给这个方法。这个参数是你想要让线程池创建的线程数。

你必须使用schedule()方法,让执行者在一段时间后执行任务。这个方法接收3个参数,如下:

你想要执行的任务

你想要让任务在执行前等待多长时间

时间单位,指定为TimeUnit类的常数

在本例中,每个任务等待的秒数(TimeUnit.SECONDS)等于它在任务数组中的位置再加1。

注意事项:如果你想在给定时间执行一个任务,计算这个日期与当前日期的差异,使用这个差异作为任务的延迟。

以下截图显示这个示例执行的输出:

89e7c57f1221605e58e6a9da9ba31906.png

你可以看出这些任务是如何开始执行的,一秒执行一个。所有任务都是同时提交给执行者的,但每个任务比之前的任务都有1秒的延迟。

不止这些…

你也可以使用Runnable接口实现任务,因为ScheduledThreadPoolExecutor类的schedule()方法接收这两种类型(Runnable和Callable)的任务。

尽管ScheduledThreadPoolExecutor类是ThreadPoolExecutor类的子类,因此,它继承 ThreadPoolExecutor类的所有功能,但Java建议使用ScheduledThreadPoolExecutor仅适用于调度任务。

最后,你可以配置ScheduledThreadPoolExecutor的行为,当你调用shutdown()方法时,并且有待处理的任务正在等待它们延迟结束。默认的行为是,不管执行者是否结束这些任务都将被执行。你可以使用ScheduledThreadPoolExecutor类的setExecuteExistingDelayedTasksAfterShutdownPolicy()方法来改变这种行为。使用false,调用 shutdown()时,待处理的任务不会被执行。

参见

在第4章,线程执行者中的执行者执行返回结果的任务指南

d0c1501a6d8bb921cf36400dc89de69f.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值