可以向CompletionService提交一系列Callable并且返回值类型为T的任务,这个completionService会将他们的Future<T>加入一个队列,然后先执行完成的能先从结果队列中取出结果。
示例程序对CompletionService提交了编号为0-9的10个Callable任务,然后编号0的会休眠10秒再返回自身编号0,编号1的会休眠9秒...依次类推编号9的会休眠1秒再返回9。
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的结果,因为它运行的时长最短,然后依次取到运行时间从短到长的结果
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