原文链接
https://blog.csdn.net/luzhouyue1024/article/details/128622978
可以向CompletionService提交一系列Callable并且返回值类型为T的任务,这个CompletionService会将他们的Future<T>加入一个队列,先执行完成的任务,先从结果队列中取出结果。符合“先完成先获取”的顺序规则。
下面用代码demo这个过程,示例程序对CompletionService提交了编号为0-9的10个Callable任务,编号0的任务,会休眠10秒再返回自身编号0;
编号1的会休眠9秒...
依次类推编号9的会休眠1秒再返回9。
猜一猜,哪个任务会先从CompletionService里返回结果呢?
package lydia.study.concurrent;
import java.util.concurrent.*;
//CompletionService使用
public class CompletionServiceTest {
public static void main(String[] args) {
int POOL_SIZE = 10;
ExecutorService executor = Executors.newFixedThreadPool(POOL_SIZE);
CompletionService<Integer> service = new ExecutorCompletionService<>(executor);
for (int i = 0; i < POOL_SIZE; i++) {
int threadId = i;
service.submit( () ->{
Thread.sleep((10 - threadId) * 1000);
return threadId;
}
);
}
for (int i = 0; i < POOL_SIZE; i++) {
try {
Future<Integer> result = service.take();
System.out.println("In loop, i=" + i + ", thread id=" + result.get());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
System.out.println(e.getCause());
}
}
executor.shutdown();
}
}
调用CompletionService的take()方法,则会先取到编号9的结果,因为它运行的时长最短,然后依次取到编号8,编号7......的结果,顺序是遵循运行时间从短到长的结果
In loop, i=0, thread id=9
In loop, i=1, thread id=8
In loop, i=2, thread id=7
In loop, i=3, thread id=6
In loop, i=4, thread id=5
In loop, i=5, thread id=4
In loop, i=6, thread id=3
In loop, i=7, thread id=2
In loop, i=8, thread id=1
In loop, i=9, thread id=0