[并发编程]并发编程第二篇:利用并发编程,实现计算大量数据的和
利用并發(fā)編程,實現(xiàn)計算大量數(shù)據(jù)的和
實現(xiàn)代碼:
package tj.pojo.generate.main;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>>();// 內(nèi)部類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;}@Overridepublic Long call() throws Exception {Long sum = 0L;for (int i = start; i < end; i++) {sum += numbers[i];}System.out.println(String.format("%s~%s的和為%s", start, end, sum));return sum;}}public ConcurrentCalculator() {cpuCoreNumber = Runtime.getRuntime().availableProcessors();System.out.println("CPU核心數(shù):" + cpuCoreNumber);exec = Executors.newFixedThreadPool(cpuCoreNumber);}public Long sum(final int[] numbers) {for (int i = 0; i < cpuCoreNumber; i++) {int increment = numbers.length / cpuCoreNumber + 1;int start = increment * i;int end = start + increment;if (end > numbers.length) {end = numbers.length;}SumCalculator task = new SumCalculator(numbers, start, end);FutureTask<Long> future = new FutureTask<Long>(task);tasks.add(future);System.out.println("添加一個任務,總?cè)蝿諗?shù)為:" + tasks.size());if (!exec.isShutdown()) {exec.submit(future);// ExecutoreService提供了submit()方法,傳遞一個Callable,或Runnable,返回Future。// exec.submit(task); }}System.out.println("任務分配完成,總?cè)蝿諗?shù)為:" + tasks.size());return getResult();}public Long getResult() {Long sums = 0L;for (Future<Long> task : tasks) {try {Long sum = task.get();sums += sum;System.out.println("當前總合計:" + sums);} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}}return sums;}public void close() {exec.shutdown();} }其中,在代碼的第62行~第64行,由于不了解ExecutoreService.submit(Runnable task)方法的功能。
同時FutureTask<Long> future和SumCalculator task都實現(xiàn)了Runnable接口,造成代碼調(diào)用時,進程一直不結(jié)束。
傳遞了FutureTask<Long> future才正確執(zhí)行。
exec.submit(future);// ExecutoreService提供了submit()方法,傳遞一個Callable,或Runnable,返回Future。// exec.submit(task);測試方法:
public static void test() {int[] numbers = new int[100];for (int i = 0; i < 100; i++) {numbers[i] = i + 1;}tj.pojo.generate.main.ConcurrentCalculator cc = new tj.pojo.generate.main.ConcurrentCalculator();Long sum = cc.sum(numbers);System.out.println("1~100的和為" + sum);cc.close();}?
FutureTask的實現(xiàn)代碼:
public class FutureTask<V> implements RunnableFuture<V>
FutureTask類實現(xiàn)了RunnableFuture接口,RunnableFuture接口的實現(xiàn)代碼:
public interface RunnableFuture<V> extends Runnable, Future<V> {
??? void run();
}
可以看出RunnableFuture繼承了Runnable接口和Future接口,而FutureTask實現(xiàn)了RunnableFuture接口。
所以它既可以作為Runnable被線程執(zhí)行,又可以作為Future得到Callable的返回值。
事實上,FutureTask是Future接口的一個唯一實現(xiàn)類。
并發(fā)編程的兩種實現(xiàn)形式:
1):使用Callable+Future獲取執(zhí)行結(jié)果
public class Test {public static void main(String[] args) {ExecutorService executor = Executors.newCachedThreadPool();Task task = new Task();Future<Integer> result = executor.submit(task);executor.shutdown();try {Thread.sleep(1000);} catch (InterruptedException e1) {e1.printStackTrace();}System.out.println("主線程在執(zhí)行任務");try {System.out.println("task運行結(jié)果"+result.get());} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}System.out.println("所有任務執(zhí)行完畢");} } class Task implements Callable<Integer>{@Overridepublic Integer call() throws Exception {System.out.println("子線程在進行計算");Thread.sleep(3000);int sum = 0;for(int i=0;i<100;i++)sum += i;return sum;} }2):使用Callable+FutureTask獲取執(zhí)行結(jié)果
public class Test {public static void main(String[] args) {//第一種方式ExecutorService executor = Executors.newCachedThreadPool();Task task = new Task();FutureTask<Integer> futureTask = new FutureTask<Integer>(task);executor.submit(futureTask);executor.shutdown();//第二種方式,注意這種方式和第一種方式效果是類似的,只不過一個使用的是ExecutorService,一個使用的是Thread/*Task task = new Task();FutureTask<Integer> futureTask = new FutureTask<Integer>(task);Thread thread = new Thread(futureTask);thread.start();*/try {Thread.sleep(1000);} catch (InterruptedException e1) {e1.printStackTrace();}System.out.println("主線程在執(zhí)行任務");try {System.out.println("task運行結(jié)果"+futureTask.get());} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}System.out.println("所有任務執(zhí)行完畢");} } class Task implements Callable<Integer>{@Overridepublic Integer call() throws Exception {System.out.println("子線程在進行計算");Thread.sleep(3000);int sum = 0;for(int i=0;i<100;i++)sum += i;return sum;} }?
轉(zhuǎn)載于:https://www.cnblogs.com/Candies/p/5692389.html
總結(jié)
以上是生活随笔為你收集整理的[并发编程]并发编程第二篇:利用并发编程,实现计算大量数据的和的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 模糊查询输入框
- 下一篇: Linux系统管理员面试50题