在java线程中,Runables接口的run方法不提供返回值,因此无法用来进行并发执行
但有一个ExecutorCompletionService可以异步提交submit(task(Callable)),
ExecutorCompletionService对Callable生成FutureTask,FutureTask完成时会执行done操作,
然后ExecutorCompletionService中得线程池executor执行task的内容并得到对应的结果放入BlockingQueue<Future>
ExecutorCompletionService进行take操作从BlockingQueue堵塞获取结果,直至所有线程的结果全部返回则将结果进行计算并返回
package com.test.concurrencalc;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class CalcBillionsIntAddInFuture {
public final static long MAX_NUM = 100000000000l;
public final static int CPUS = Runtime.getRuntime().availableProcessors();
private final ExecutorService executor;
private final ExecutorCompletionService<Long> ecs;
private final long maxValue;
public CalcBillionsIntAddInFuture(long maxValue) {
// TODO Auto-generated constructor stub
executor = Executors.newFixedThreadPool(CPUS);
ecs = new ExecutorCompletionService<>(executor);
this.maxValue = maxValue;
}
private class CalcIntAddTask implements Callable<Long>{
private final int i;
public CalcIntAddTask(int i) {
// TODO Auto-generated constructor stub
this.i = i;
}
@Override
public Long call() throws Exception {
// TODO Auto-generated method stub
long res = 0;
for(long v=maxValue/CPUS*i+1;v<=maxValue/CPUS*(i+1);v++){
res += v;
}
return res;
}
}
public void calcIntValues(){
for(int i=0;i<CPUS;i++){
ecs.submit(new CalcIntAddTask(i));
}
long res = 0;
Future<Long> future = null;
for(int i=0;i<CPUS;i++){
try {
future = ecs.take();
res += future.get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
executor.shutdown();
System.out.println("res:" + res);
}
public static void main(String[] args) {
CalcBillionsIntAddInFuture calcBillionsIntAddInFuture = new CalcBillionsIntAddInFuture(MAX_NUM);
long start = System.currentTimeMillis();
calcBillionsIntAddInFuture.calcIntValues();
System.out.println("method in Future calc time:"+(System.currentTimeMillis() - start));
start = System.currentTimeMillis();
long res = 0;
for(long i=1;i<=MAX_NUM;i++){
res += i;
}
System.out.println("res:"+res);
System.out.println("method2 calc time:"+(System.currentTimeMillis() - start));
}
}