标签:
本篇演示3个数组求和的例子。package cn.fansunion.executorservice;
public class BasicCaculator {
public static long sum(int[] numbers){
long sum = 0;
for(int i=0;i<numbers.length;i++){
sum += numbers[i];
}
return sum;
}
}package cn.fansunion.executorservice;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
//并发计算数组的和,“同步”求和
public class ConcurrentCalculator {
private ExecutorService exec;
//这个地方,纯粹是“一厢情愿”,“并行执行”不受咱们控制,取决于操作系统的“态度”
private int cpuCoreNumber;
private List<Future<Long>> tasks = new ArrayList<Future<Long>>();
class SumCalculator implements Callable<Long> {
private int[] numbers;
private int start;
private int end;
public SumCalculator(final int[] numbers, int start, int end) {
this.numbers = numbers;
this.start = start;
this.end = end;
}
public Long call() throws Exception {
Long sum = 0L;
for (int i = start; i < end; i++) {
sum += numbers[i];
}
return sum;
}
}
public ConcurrentCalculator() {
cpuCoreNumber = Runtime.getRuntime().availableProcessors();
exec = Executors.newFixedThreadPool(cpuCoreNumber);
}
public Long sum(final int[] numbers) {
// 根据CPU核心个数拆分任务,创建FutureTask并提交到Executor
for (int i = 0; i < cpuCoreNumber; i++) {
int increment = numbers.length / cpuCoreNumber + 1;
int start = increment * i;
int end = increment * i + increment;
if (end > numbers.length)
end = numbers.length;
SumCalculator subCalc = new SumCalculator(numbers, start, end);
FutureTask<Long> task = new FutureTask<Long>(subCalc);
tasks.add(task);
if (!exec.isShutdown()) {
exec.submit(task);
}
}
return getResult();
}
/**
* 迭代每个只任务,获得部分和,相加返回
*/
public Long getResult() {
Long result = 0l;
for (Future<Long> task : tasks) {
try {
// 如果计算未完成则阻塞
Long subSum = task.get();
result += subSum;
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
return result;
}
public void close() {
exec.shutdown();
}
}package cn.fansunion.executorservice;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
//并发计算数组的和,“异步”求和
public class ConcurrentCalculatorAsync {
private ExecutorService exec;
private CompletionService<Long> completionService;
//这个地方,纯粹是“一厢情愿”,“并行执行”不受咱们控制,取决于操作系统的“态度”
private int cpuCoreNumber;
class SumCalculator implements Callable<Long> {
private int[] numbers;
private int start;
private int end;
public SumCalculator(final int[] numbers, int start, int end) {
this.numbers = numbers;
this.start = start;
this.end = end;
}
public Long call() throws Exception {
Long sum = 0l;
for (int i = start; i < end; i++) {
sum += numbers[i];
}
return sum;
}
}
public ConcurrentCalculatorAsync() {
cpuCoreNumber = Runtime.getRuntime().availableProcessors();
exec = Executors.newFixedThreadPool(cpuCoreNumber);
completionService = new ExecutorCompletionService<Long>(exec);
}
public Long sum(final int[] numbers) {
// 根据CPU核心个数拆分任务,创建FutureTask并提交到Executor
for (int i = 0; i < cpuCoreNumber; i++) {
int increment = numbers.length / cpuCoreNumber + 1;
int start = increment * i;
int end = increment * i + increment;
if (end > numbers.length){
end = numbers.length;
}
SumCalculator subCalc = new SumCalculator(numbers, start, end);
if (!exec.isShutdown()) {
completionService.submit(subCalc);
}
}
return getResult();
}
/**
* 迭代每个只任务,获得部分和,相加返回
*/
public Long getResult() {
Long result = 0l;
for (int i = 0; i < cpuCoreNumber; i++) {
try {
Long subSum = completionService.take().get();
result += subSum;
System.out.println("subSum="+subSum+",result="+result);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
return result;
}
public void close() {
exec.shutdown();
}
}package cn.fansunion.executorservice;
import java.math.BigDecimal;
//数组求和3个Demo
public class ArraySumDemo {
public static void main(String[] args) {
int n = 200000000;
int[] numbers = new int[n];
for(int i=1;i<=n;i++){
numbers[i-1]=i;
}
basic(numbers);
long time = System.currentTimeMillis();
concurrentCaculatorAsync(numbers);
long endTime=System.currentTimeMillis();
System.out.println("多核并行计算,异步相加:"+time(time,endTime));
long time2 = System.currentTimeMillis();
concurrentCaculator(numbers);
long endTime2=System.currentTimeMillis();
System.out.println("多核并行计算,同步相加:"+time(time2,endTime2));
}
private static void basic(int[] numbers) {
long time1 = System.currentTimeMillis();
long sum=BasicCaculator.sum(numbers);
long endTime1 = System.currentTimeMillis();
System.out.println("单线程:"+time(time1,endTime1));
System.out.println("Sum:"+sum);
}
private static double time(long time, long endTime) {
long costTime = endTime-time;
BigDecimal bd = new BigDecimal(costTime);
//本来想着,把毫秒转换成秒的,最后发现计算太快了
BigDecimal unit = new BigDecimal(1L);
BigDecimal s= bd.divide(unit,3);
return s.doubleValue();
}
//并行计算,“同步”求和
private static void concurrentCaculator(int[] numbers) {
ConcurrentCalculator calc = new ConcurrentCalculator();
Long sum = calc.sum(numbers);
System.out.println(sum);
calc.close();
}
//并行计算,“异步”求和
private static void concurrentCaculatorAsync(int[] numbers) {
ConcurrentCalculatorAsync calc = new ConcurrentCalculatorAsync();
Long sum = calc.sum(numbers);
System.out.println("Sum:"+sum);
calc.close();
}
}标签:
原文地址:http://blog.csdn.net/fansunion/article/details/50433904