标签:
本篇演示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