使用CompletionService来实现对任意一个线程运行完后的结果的及时获取。它内部添加了阻塞队列,从而获取feture中的值,然后根据返回值做对应的处理。
代码示例如下:
package com.dalingjia.thead.future;
import java.util.Random;
import java.util.concurrent.*;
/**
* 先执行完的线程先处理的方案
*/
public class testCallable {
public static void main(String[] args) {
try {
completionServiceCount();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 使用CompletionService收集callable结果
* @throws ExecutionException
* @throws InterruptedException
*/
public static void completionServiceCount() throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newCachedThreadPool();
CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(executorService);
int threadNum = 5;
for (int i = 0; i < threadNum; i++) {
completionService.submit(getTask(i));
}
int sum = 0;
int temp = 0;
for (int i = 0; i < threadNum; i++) {
temp = completionService.take().get();
sum += temp;
System.out.print(temp + "\t");
}
System.out.println("CompletionService all is : " + sum);
executorService.shutdown();
}
public static Callable<Integer> getTask(final int no) {
final Random rand = new Random();
Callable<Integer> task = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
int time = rand.nextInt(100) * 100;
System.out.println("thread:" + no + ",sleep time is:" + time);
Thread.sleep(time);
return no;
}
};
return task;
}
}
打印结果:
thread:0,sleep time is:1100
thread:1,sleep time is:4300
thread:2,sleep time is:4300
thread:3,sleep time is:4400
thread:4,sleep time is:1900
0 4 2 1 3 CompletionService all is : 10
如果想获取最先返回的一个结果,可以使用System.out.println(completionService.take().get()); 不使用循环。
参考博客:Java利用CompletionService异步获取多线程执行结果,CompletionService异步非阻塞获取并行任务执行结果