一般咱們使用程序處理計算,常見的有單線程,JUC下單的多線程,還有優秀的ForkJoin框架(與遞歸形式上類似卻又優於遞歸),直接上代碼吧java
1 package com.fork; 2 3 import java.util.concurrent.ExecutionException; 4 import java.util.concurrent.ForkJoinPool; 5 import java.util.concurrent.ForkJoinTask; 6 import java.util.concurrent.RecursiveTask; 7 10 11 public class ForkDemo extends RecursiveTask<Long>{ 12 private long end; 13 private final long THRELOD = 500000000L; 14 private long start; 15 public ForkDemo(long start ,long end) { 16 this.end = end; 17 this.start = start; 18 } 19 20 @Override 21 protected Long compute() { 22 long v = 0; 23 if( end - start <= THRELOD) { 24 for (long i = start; i <= end; i++) { 25 v += i; 26 } 27 return v; 28 }else { 29 long middle = (end + start)/2; 30 ForkDemo demo1 = new ForkDemo(start, middle); 31 ForkDemo demo2 = new ForkDemo(middle+1, end); 32 demo1.fork(); 33 demo2.fork(); 34 return demo1.join() + demo2.join(); 35 36 } 37 } 38 }
這是ForkJoin的基本示例使用,如下是三種計算的比較;多線程
package com.fork; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinTask; import java.util.concurrent.Future; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class LockDemo { // 單線程方式 public static long execSingle(long n) { long sum = 0; for (long i = 1; i <= n; i++) { sum += i; } System.out.println("the sum = " + sum); return sum; } // 多線程方式 public static long execMult(long n) throws ExecutionException { long value = 0L; ExecutorService exect = Executors.newFixedThreadPool(3); ArrayList<Callable<Long>> list =new ArrayList<Callable<Long>>(); long total; list.add(()->{ long sum = 0L; for(Long i=1L;i<=n;i+=3) { sum += i; } return sum; }); list.add(()->{ long sum = 0L; for(Long i=2L;i<=n;i+=3) { sum += i; } return sum; }); list.add(()->{ long sum = 0L; for(Long i=3L;i<=n;i+=3) { sum += i; } return sum; }); List<Future<Long>> end =null; try { end = exect.invokeAll(list); for(Future<Long> t:end) { value += t.get(); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } exect.shutdownNow(); System.out.println("this end is " + value); return value; } public static void main(String[] args) throws ExecutionException { Long start1 = System.currentTimeMillis(); execSingle(3800000000L); Long end1 = System.currentTimeMillis(); System.out.println("單線程下:end1 - start1 = " +(end1-start1) ); Long start2 = System.currentTimeMillis(); execMult(3800000000L); Long end2 = System.currentTimeMillis(); System.out.println("多線程下:end2 - start2 = " +(end2-start2) ); Long start3 = System.currentTimeMillis(); ForkJoinPool pool = new ForkJoinPool(); ForkDemo demo = new ForkDemo(0L, 3800000000L); ForkJoinTask<Long> task = pool.submit(demo); Long end3 = System.currentTimeMillis(); System.out.println("forkjoin框架下:end3 - start3 = " +(end3-start3) ); try { System.out.println(task.get()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
最後控制檯輸出:(ForkJoin 優秀啊.....此處向大神Doug Lea模拜......)框架
注意ForkJoin須要使用合理的細分程度,這裏多線程計算時間誇張了點.....具體情境仍是要具體分析,有些狀況多線程不必定比多線程快(有線程切換的代價),多線程須要互不依賴,如爬取圖片,以此我也不知道....多線程花了這麼多時間,哪位大佬給分下.....ide