Fork/Join框架是JDK1.7引入的并行计算框架,核心概念:
1. 将大任务自动递归分解成小任务并行执行;
2. 工作窃取(work-stealing)算法,空闲线程从另一个任务队列获取任务并执行,避免计算资源闲置。
譬如,要生产10000个蛋糕,可以将其分解成100个任务,每次生产100个。工人1和工人2分别领取50个任务。假如工人1完成30个任务时,工人2已经完成了自己的任务队列,那么工人2会从工人1中获取任务并执行。
/**
* Fork/Join入门示例
*@author Tony.Lau
*/
public class ForkJoinDemo {
public static void main(String[]args)throws InterruptedException, ExecutionException {
int size = 10000;
List
for (int i = 0; i <size;i++) {
list.add(new Cake(-1, -1));
}
long start = System.currentTimeMillis();
ForkJoinPoolpool =new ForkJoinPool();
Tasktask =new Task(list, 0, size);
pool.execute(task);
while (!task.isDone()){
Thread.sleep(100);
}
pool.shutdown();
if (task.isCompletedNormally()) {
System.out.println("UsedTime: " + (System.currentTimeMillis() -start));
}
for (int i = 0; i <size;i++) {
if (i % 100 == 0) {
System.out.println(list.get(i));
}
}
}
}
/**
* 无返回值的任务继承RecursiveAction并重写compute()方法
*@author Tony.Lau
*/
class Taskextends RecursiveAction {
private static final long serialVersionUID = 3076674975132715659L;
private final List
private int first;
private int last;
public Task(List
this.list =list;
this.first =first;
this.last =last;
}
/**
* 1.递归分解任务的结束条件
* 2.递归分解任务的分解方法
*/
@Override
protected void compute() {
if (last -first < 1000) {
make();
}else {
int middle = (first +last) / 2;
Taskt1 =new Task(list,first,middle + 1);
Taskt2 =new Task(list,middle + 1,last);
invokeAll(t1,t2);
}
}
private void make() {
System.out.println("first:" +first +"----Last:" +last);
for (int i =first;i <last;i++) {
list.set(i,new Cake(i,i));
}
}
}
class Cake {
private int milk;
private int water;
public Cake(int milk,int water) {
this.milk =milk;
this.water =water;
}
@Override
public String toString() {
return "Cake [milk=" + milk +", water=" +water +"]";
}
}