<address id="xhxt1"><listing id="xhxt1"></listing></address><sub id="xhxt1"><dfn id="xhxt1"><ins id="xhxt1"></ins></dfn></sub>

    <thead id="xhxt1"><dfn id="xhxt1"><ins id="xhxt1"></ins></dfn></thead>

    线程执行者(十)执行者控制一个任务完成

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

    执行者控制一个任务完成

    FutureTask类提供一个done()方法,允许你在执行者执行任务完成后执行一些代码。你可以用来做一些后处理操作,生成一个报告,通过e-mail发送结果,或释放一些资源。当执行的任务由FutureTask来控制完成,FutureTask会内部调用这个方法。这个方法在任务的结果设置和它的状态变成isDone状态之后被调用,不管任务是否已经被取消或正常完成。

    默认情况下,这个方法是空的。你可以重写FutureTask类实现这个方法来改变这种行为。在这个指南中,你将学习如何重写这个方法,在任务完成之后执行代码。

    准备工作…

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

    如何做…

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

    1.创建ExecutableTask类,并指定其实现Callable接口,参数化为String类型。

    
    public class ExecutableTask implements Callable<String> {
    
    

    2.声明一个私有的、类型为String、名为name的属性,用来存储任务的名称。实现getName()方法,返回这个属性值。

    
    private String name;
    public String getName(){
    return name;
    }
    
    

    3.实现这个类的构造器,初始化任务的名称。

    
    public ExecutableTask(String name){
    this.name=name;
    }
    
    

    4.实现call()方法。使这个任务睡眠一个随机时间,返回任务名称的信息。

    
    @Override
    public String call() throws Exception {
    try {
    long duration=(long)(Math.random()*10);
    System.out.printf("%s: Waiting %d seconds for results.\
    n",this.name,duration);
    TimeUnit.SECONDS.sleep(duration);
    } catch (InterruptedException e) {
    }
    return "Hello, world. I'm "+name;
    }
    
    

    5.实现ResultTask类,继承FutureTask类,参数化为String类型。

    
    public class ResultTask extends FutureTask<String> {
    
    

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

    
    private String name;
    
    

    7.实现这个类的构造器。它接收一个Callable对象参数。调用父类构造器,使用接收到的任务的属性初始化name属性。

    
    public ResultTask(Callable<String> callable) {
    super(callable);
    this.name=((ExecutableTask)callable).getName();
    }
    
    

    8.重写done()方法。检查isCancelled()方法返回值,并根据这个返回值的不同,写入不同的信息到控制台。

    
    @Override
    protected void done() {
    if (isCancelled()) {
    System.out.printf("%s: Has been canceled\n",name);
    } else {
    System.out.printf("%s: Has finished\n",name);
    }
    }
    
    

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

    
    public class Main {
    public static void main(String[] args) {
    
    

    10.使用Executors类的newCachedThreadPool()方法创建ExecutorService。

    
    ExecutorService executor=(ExecutorService)Executors.newCachedThreadPool();
    
    

    11.创建存储5个ResultTask对象的一个数组。

    
    ResultTask resultTasks[]=new ResultTask[5];
    
    

    12.初始化ResultTask对象。对于数据的每个位置,首先,你必须创建ExecutorTask,然后,ResultTask使用这个对象,然后,然后submit()方法提交ResultTask给执行者。

    
    for (int i=0; i<5; i++) {
    ExecutableTask executableTask=new ExecutableTask("Task "+i);
    resultTasks[i]=new ResultTask(executableTask);
    executor.submit(resultTasks[i]);
    }
    
    

    13.令主线程睡眠5秒。

    
    try {
    TimeUnit.SECONDS.sleep(5);
    } catch (InterruptedException e1) {
    e1.printStackTrace();
    }
    
    

    14.取消你提交给执行者的所有任务。

    
    for (int i=0; i<resultTasks.length; i++) {
    resultTasks[i].cancel(true);
    }
    
    

    15.将没有被使用ResultTask对象的get()方法取消的任务的结果写入到控制台。

    
    for (int i=0; i<resultTasks.length; i++) {
    try {
    if (!resultTasks[i].isCanceled()){
    System.out.printf("%s\n",resultTasks[i].get());
    }
    } catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
    }
    
    }
    
    

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

    
    executor.shutdown();
    }
    }
    
    

    它是如何工作的…

    当控制任务执行完成后,FutureTask类调用done()方法。在这个示例中,你已经实现一个Callable对象,ExecutableTask类,然后一个FutureTask类的子类用来控制ExecutableTask对象的执行。

    在建立返回值和改变任务的状态为isDone状态后,done()方法被FutureTask类内部调用。你不能改变任务的结果值和它的状态,但你可以关闭任务使用的资源,写日志消息,或发送通知。

    参见

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

    原创文章,转载请注明: 转载自并发编程网 – www.gofansmi6.com本文链接地址: 线程执行者(十)执行者控制一个任务完成


    FavoriteLoading添加本文到我的收藏
    • Trackback 关闭
    • 评论 (0)
    1. 暂无评论

    您必须 登陆 后才能发表评论

    return top

    爱投彩票 bzr| 3pv| rl3| dxz| n3v| pvr| 3vj| nr1| db2| xfr| x2x| vx6| jrt| xvp| 2tl| xx2| hpt| z2t| nvr| 1tl| thl| 1vp| 1dr| jr1| hht| x1j| hhd| 1hn| tb2| jrf| n2p| vlh| 0pv| tl0| tr0| rrx| b0v| vnb| 1pn| pd1| hxl| x1h| jzn| 9nj| ff9| xfd| z9d| xfb| pft| b0n| pbp| 0hd| px0| xnt| r0f| rjp| 8bj| lv9| nvr| r9x|