[笔记][Java7并发编程实战手册]4.11-4.12在执行器中分离任务的启动和结果的处理和处理在执行器中被拒绝的任务

来源:互联网 发布:shift js按键 编辑:程序博客网 时间:2024/05/18 20:50

[笔记][Java7并发编程实战手册]系列目录


简介

  1. 将启动任务和完成任务的结果分离的服务:
    interface CompletionService:
      将启动任务和完成任务的结果分离的服务。使用submit来提交任务。使用take或则poll来获取已完成任务的future对象。可以用来管理异步io,执行读操作,当完成读操作时,可以在程序的不同部分获取结果。该服务依赖一个 ExecutorService 来执行任务。

  2. 处理在执行器中被拒绝的任务。
    在之前的章节中说到过,调用执行器的shutdown()方法后,该执行器不再接受新的任务,并且抛出异常,这个任务就是被拒绝的任务。而 ThreadPoolExecutor提供了处理该类任务的机制。RejectedExecutionHandler


本章使用心得

  1. CompletionService相当于一个服务,关闭执行器就相当于关闭了服务。因为服务依赖于执行器。
  2. take() 获取队列中已完成任务的结果,如果队列为空则一直阻塞,直到有可用结果,并弹出且从队列中移除该结果
  3. poll() 获取队列中已完成任务的结果,唯一与take不同的是,如果队列为空,则直接返回null,不阻塞
  4. 从粗略的了解来看,CompletionService 和 我们自己拿到任务的future对象然后传递给其他对象处理结果的效果差不多。只是该类封装了其中的一些处理,比如获取已经完成的任务结果。
  5. RejectedExecutionHandler用来处理被拒绝的任务接口,由于执行器可以接收Runnable和callable,但是该接口返回的任务实际上是一个 futureTask。这个类不能获取人物类的详细信息。

示例

分离任务的启动和结果的处理

场景描述:以下代码只是很简单的演示了,怎么把任务提交给服务,怎么在另外一个线程中怎么获取服务中已完成任务的结果。

/** * Created by zhuqiang on 2015/9/4 0004. */public class Client {    public static void main(String[] args) throws InterruptedException {        ExecutorService es = Executors.newCachedThreadPool();        CompletionService cs = new ExecutorCompletionService(es);  //服务依赖 一个线程池        cs.submit(new Task("小强1"));        cs.submit(new Task("小小强"));        HanderResult hr = new HanderResult(cs);        Thread t = new Thread(hr);        t.start();//        es.shutdown();//        es.awaitTermination(1, TimeUnit.MILLISECONDS);//        hr.setFlag(false); //设置 获取结果的线程执行完成、 想要控制这个服务结束 还真是有点麻烦,在 hr线程中会得不到 任务是否完成。所以我觉得这个类就如类名一样,只适合做服务,不适合关闭        System.out.println("main:结束");    }}//执行任务类class Task implements Callable<String> {    private String name;    public Task(String name) {        this.name = name;    }    @Override    public String call() throws Exception {        long time = (long) (Math.random() * 10);        System.out.printf("%s,%s,执行任务耗时=%s\n", Thread.currentThread().getName(), name, time);        TimeUnit.SECONDS.sleep(time);        return name;    }}//任务处理结果类class HanderResult implements Runnable {    CompletionService cs;    private boolean flag = true;    public HanderResult(CompletionService cs) {        this.cs = cs;    }    @Override    public void run() {        while (flag) {            try {//                Future take = cs.take();  //该方法会阻塞直到能获取到任务结果                Future poll = cs.poll();                if (poll != null) {                    System.out.println("结果:" + poll.get());                }            } catch (InterruptedException e) {                e.printStackTrace();            } catch (ExecutionException e) {                e.printStackTrace();            }        }    }    public boolean isFlag() {        return flag;    }    public void setFlag(boolean flag) {        this.flag = flag;    }}

某一次的运行结果:

pool-1-thread-2,小小强,执行任务耗时=8main:结束pool-1-thread-1,小强1,执行任务耗时=5结果:小强1结果:小小强

处理被拒绝的任务

场景描述:以下演示了,由于执行器被关闭,而又提交了新任务,该任务会被执行器拒绝,那么就来处理被拒绝的任务。

/** * Created by zhuqiang on 2015/9/4 0004. */public class Client {    public static void main(String[] args) {        ThreadPoolExecutor tpl =  (ThreadPoolExecutor)Executors.newCachedThreadPool();        tpl.setRejectedExecutionHandler(new MyHander());        tpl.submit(new Task("小强"));        tpl.shutdown();//        tpl.submit(new Task("小小强"));        tpl.submit(new TaskCal("有返回结果的 task"));    }}// 任务类class  Task implements Runnable{    private  String name;    public Task(String name) {        this.name = name;    }    @Override    public void run() {        System.out.println(Thread.currentThread().getName() + "...." + name);    }    @Override    public String toString() {        return "Task{" +                "name='" + name + '\'' +                '}';    }}// 任务类class  TaskCal implements Callable<String>{    private  String name;    public TaskCal(String name) {        this.name = name;    }    @Override    public String call() throws Exception {        System.out.println(Thread.currentThread().getName() + "...." + name);        return name;    }}//处理 拒绝任务的 处理类class MyHander implements RejectedExecutionHandler{    @Override    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {        FutureTask ft = (FutureTask) r;        System.out.printf("执行器状态:%s,任务:%s",executor.isShutdown(),r.toString());    }}

某一次的运行结果:

pool-1-thread-1....小强执行器状态:true,任务:java.util.concurrent.FutureTask@7f31245a

结果说明:
1. 可以看到 在例子在返回被拒绝任务的时候 是一个FutureTask对象。但是该对象不能获取到任务的详细信息。所以不知道在处理任务的时候,怎么来分辨是哪一个任务呢?

0 0
原创粉丝点击