通过Callable,Future实现十亿数据的并行相加

来源:互联网 发布:软件项目总结 编辑:程序博客网 时间:2024/05/22 11:46

在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;

privatefinal long maxValue;

public CalcBillionsIntAddInFuture(longmaxValue) {

// TODO Auto-generated constructor stub

executor = Executors.newFixedThreadPool(CPUS);

ecs = new ExecutorCompletionService<>(executor);

this.maxValue =maxValue;

}

private class CalcIntAddTask implements Callable<Long>{


privatefinal int i;

public CalcIntAddTask(inti) {

// TODO Auto-generated constructor stub

this.i =i;

}

@Override

public Long call()throws Exception {

// TODO Auto-generated method stub

long res = 0;

for(longv=maxValue/CPUS*i+1;v<=maxValue/CPUS*(i+1);v++){

res += v;

}

returnres;

}

}

public void calcIntValues(){

for(inti=0;i<CPUS;i++){

ecs.submit(new CalcIntAddTask(i));

}

long res = 0;

Future<Long> future =null;

for(inti=0;i<CPUS;i++){

try {

future = ecs.take();

res += future.get();

} catch (InterruptedExceptione) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (ExecutionExceptione) {

// 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(longi=1;i<=MAX_NUM;i++){

res += i;

}

System.out.println("res:"+res);

System.out.println("method2 calc time:"+(System.currentTimeMillis() -start));

}

}


0 0
原创粉丝点击