一、ExecutorCompletionService:提交任务线程,每个线程任务直线完成后,将返回值放在阻塞队列中,而后能够经过阻塞队列的take()方法返回 对应线程的执行结果,是Executor和BlockingQueue的结合体,xecutorCompletionService在构造函数中会建立一个BlockingQueue(使用的基于链表的无界队列LinkedBlockingQueue),该BlockingQueue的做用是保存Executor执行的结果。当计算完成时,调用FutureTask的done方法。当提交一个任务到ExecutorCompletionService时,首先将任务包装成QueueingFuture,它是FutureTask的一个子类,而后改写FutureTask的done方法,以后把Executor执行的计算结果放入BlockingQueue中html
submit的task不必定是按照加入本身维护的list顺序完成的。函数
从list中遍历的每一个Future对象并不必定处于完成状态,这时调用get()方法就会被阻塞住,若是系统是设计成每一个线程完成后就能根据其结果继续作后面的事,这样对于处于list后面的可是先完成的线程就会增长了额外的等待时间。spa
而CompletionService的实现是维护一个保存Future对象的BlockingQueue。只有当这个Future对象状态是结束的时候,才会加入到这个Queue中,take()方法其实就是Producer-Consumer中的Consumer。它会从Queue中取出Future对象,若是Queue是空的,就会阻塞在那里,直到有完成的Future对象加入到Queue中。线程
二、futureTask:任务状态由变量state表示,任务状态都基于state判断。而futureTask的阻塞则是经过自旋(for循环)+挂起线程(spark)实现.揭秘futureTask设计