1.ForkJoin框架
簡單的數列求和demo
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
/**
* 分而治之數列求和
* 分而治之可以有效處理量數據,把數據分成批次進行處理,然後再整合起來獲得結果。
* 注意:如果劃分層次太深,一直得不到返回,1線程數量太多,系統性能嚴重下降;2棧溢出。
* RecursiveTask<Long>返回V類型、RecursiveAction無返回類型;均繼承ForkJoinTask。
* @author wsz
* @date 2017年12月6日
*/
public class ForkJoinDemo extends RecursiveTask<Long>{
private static final long serialVersionUID = 1L;
//臨界值
private static final int THRESHOLD = 1000;
private long start ;
private long end;
public ForkJoinDemo(long start, long end) {
this.start = start;
this.end = end;
}
//需要實現繼承的抽象方法
@Override
protected Long compute() {
long sum = 0L;
boolean canCompute = (end - start) < THRESHOLD;//判斷是否可分割
if(canCompute) {//小於可分割界限,直接進行計算
for(long i = start; i<end ; i++) {
sum +=i;
}
}else {//進行分割
long step = (start+end)/100;//小任務組數
ArrayList<ForkJoinDemo> subTasks = new ArrayList<ForkJoinDemo>();
long pos = start;
for (int i = 0; i < 100; i++) {
long lastOne = pos+step;//當前組任務界限
if(lastOne > end) //到達最後
lastOne = end;
ForkJoinDemo subTask = new ForkJoinDemo(pos, lastOne);
subTasks.add(subTask);
subTask.fork();//fork後將開啓一個新線程,需要注意性能
pos += step+1;//進行下一組
}
for (ForkJoinDemo forkJoinDemo : subTasks) {
sum += forkJoinDemo.join();
}
}
return sum;
}
public static void main(String[] args) {
ForkJoinPool forkJoinPool = new ForkJoinPool();//使用線程池,fork後不會立即開啓線程,用於節省系統資源
ForkJoinDemo task = new ForkJoinDemo(0L,5000L);
ForkJoinTask<Long> result = forkJoinPool.submit(task);
Long res;
try {
res = result.get();//若任務還沒結束,將進行等待
System.out.println(res);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
2.JDK併發容器