Java中ExecutorService和CompletionService区别

分享一篇关于Java中ExecutorService和CompletionService区别,有须要的朋友能够参考一下。java

咱们如今在Java中使用多线程一般不会直接用Thread对象了,而是会用到java.util.concurrent包下的ExecutorService类来初始化一个线程池供咱们使用。多线程

以前我一直习惯本身维护一个list保存submit的callable task所返回的Future对象。线程

在主线程中遍历这个list并调用Future的get()方法取到Task的返回值。设计

可是,我在不少地方会看到一些代码经过CompletionService包装ExecutorService,而后调用其take()方法去取Future对象。之前没研究过这二者之间的区别。对象

今天看了源代码以后就明白了。get

这二者最主要的区别在于submit的task不必定是按照加入本身维护的list顺序完成的。it

从list中遍历的每一个Future对象并不必定处于完成状态,这时调用get()方法就会被阻塞住,若是系统是设计成每一个线程完成后就能根据其结果继续作后面的事,这样对于处于list后面的可是先完成的线程就会增长了额外的等待时间。io

而CompletionService的实现是维护一个保存Future对象的BlockingQueue。只有当这个Future对象状态是结束的时候,才会加入到这个Queue中,take()方法其实就是Producer-Consumer中的Consumer。它会从Queue中取出Future对象,若是Queue是空的,就会阻塞在那里,直到有完成的Future对象加入到Queue中。线程池

相关文章
相关标签/搜索