java进阶-线程池-番外-CompletionService类

这个类--JDK源码上没有标明出处,有故事,抱着学习的态度,某度了下 No Found (:

java进阶-线程池-番外-CompletionService类

这个方法的主要目的是可以获取到完成的任务,从而避免因为任务队列顺序的原因导致:前面的线程任务阻塞后面已经完成的任务被获取。

1.接口 CompletionService

java进阶-线程池-番外-CompletionService类

//两个作用:提交任务、获取已完成任务的Future
public interface CompletionService<V> {
    //提交Callable任务,并返回表示执行结果的Future实例
    Future<V> submit(Callable<V> task);

    //提交Runnable任务,并返回表示任务的Future实例,通过该实例可以了解当前任务的执行状态
    Future<V> submit(Runnable task, V result);

    //检索并移除表示下一个已完成任务的Future;等待(如果尚未存在)
    Future<V> take() throws InterruptedException;

    //检索并移除表示下一个已完成任务的Future;如果没有则返回null
    Future<V> poll();

    //检索并移除表示下一个已完成任务的Future;如果没有则等待,超时返回null
    Future<V> poll(long timeout, TimeUnit unit) throws InterruptedException;
}

2.实现类ExecutorCompletionService

java进阶-线程池-番外-CompletionService类

这个类的特点: 使用的是BlockingQueue<T> 队列

老是简单介绍每个方法我觉得没什么进步的,站高一点看看这个类怎么做的那些事吧

1.提交线程任务,拿线程完成的Future

那先说一下任务的set / get 动作在类中那些地方实现

(1)提交线程任务:

java进阶-线程池-番外-CompletionService类

方法列表中的submit就是提交任务的方法,方法中的execute() 执行 -- 非常典型的工厂模式调用,具体实现体在子类中

java进阶-线程池-番外-CompletionService类

私有内部类,重写了FutureTask 的 done 回调方法 ,在任务执行完之后执行done()  将任务添加到 completionQueue 队列中

(2)取 已完成 的线程任务,就是Queue中取值

java进阶-线程池-番外-CompletionService类

ExecutorCompletionService类中Queue 实例化的是 LinkedBlockingQueue ,take()poll()poll(timeOut,unit); (ps. 这里在分析Queue的内部实现那就东西多了,后期补上 BlockingQueue的知识)