通常我们使用程序处理计算,常见的有单线程,JUC下单的多线程,还有优秀的ForkJoin框架(与递归形式上相似却又优于递归),直接上代码吧
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需要使用合理的细分程度,这里多线程计算时间夸张了点.....具体情境还是要具体分析,有些情况多线程不一定比多线程快(有线程切换的代价),多线程需要互不依赖,如爬取图片,以此我也不知道....多线程花了这么多时间,哪位大佬给分下.....