JUC练习13——forkJoin
什么是forkjoin?
就是将单线程下的一个大任务,拆分成多个小任务,将多个小任务派给其它线程执行,最终将所有执行的结果汇总得到最终的结果
本质是:将单线程的大任务转成多线程的小任务,所以对于大任务有效率上的提高。
例如线程1上的任务执行forkJoin后分为了四个任务,这四个任务放在双端队列中等待线程1执行。
另外一个线程2刚刚完成了其它的任务此时处于空闲状态,在forkjoin下 它会执行工作窃取,去
线程1的双端队列中,从另一个端窃取线程进行执行。

2,java中如何使用forkjoin
- 继承类 ForkJoinTask<V>的子类编写一个任务类:RecursiveAction为递归事件无返回值,或者RecursiveTask为递归任务有返回值
- 实现对应的抽象方法compute
- 将实例化的任务对象交给ForkJoinPool执行
@Test
public void test11() throws ExecutionException, InterruptedException {
long start = System.currentTimeMillis();
ForkJoinPool forkJoinPool = new ForkJoinPool();//建立forkjoin池
forkjoinDemo task = new forkjoinDemo(0, 10_0000_0000);//创建一个任务
ForkJoinTask<Long> submit = forkJoinPool.submit(task);//提交任务
long sum =submit.get();//获取任务的最终结构
long end = System.currentTimeMillis();
System.out.println("sum = "+sum+" time = "+(end-start));//395
}
import java.util.concurrent.RecursiveTask;
/**
* 这是一个任务类
* compute方法是对任务的拆分
*/
public class forkjoinDemo extends RecursiveTask<Long> {
private long start;
private long end;
private long temp=10000L;
forkjoinDemo(long start,long end)
{
this.start=start;
this.end=end;
}
@Override
protected Long compute() {
long sum=0L;
if ((end-start)<temp) {
for (long i = start; i < end; i++) {
sum += i;
}
return sum;
}else
{
//将任务进行分解
long middle = (start+end)/2;
forkjoinDemo forkjoinDemo1 = new forkjoinDemo(start, middle);
forkjoinDemo forkjoinDemo2 = new forkjoinDemo(middle+1, end);
forkjoinDemo1.fork();//将任务压入队列
forkjoinDemo2.fork();//将任务压入队列
return forkjoinDemo1.join()+forkjoinDemo2.join();
}
}
}
3,对比测试,发现还是stream流的计算速度最快
@Test
public void test10()
{
long sum =0;
long start = System.currentTimeMillis();
for (long i=0;i<=10_0000_0000;i++)
{
sum +=i;
}
long end = System.currentTimeMillis();
System.out.println("sum = "+sum+" time = "+(end-start));//445
}
@Test
public void test11() throws ExecutionException, InterruptedException {
long start = System.currentTimeMillis();
ForkJoinPool forkJoinPool = new ForkJoinPool();//建立forkjoin池
forkjoinDemo task = new forkjoinDemo(0, 10_0000_0000);//创建一个任务
ForkJoinTask<Long> submit = forkJoinPool.submit(task);//提交任务
long sum =submit.get();//获取任务的最终结构
long end = System.currentTimeMillis();
System.out.println("sum = "+sum+" time = "+(end-start));//395
}
@Test
public void test12() {
long start = System.currentTimeMillis();
long sum =LongStream.rangeClosed(0,10_0000_0000L).parallel().reduce(0,Long::sum);
long end = System.currentTimeMillis();
System.out.println("sum = "+sum+" time = "+(end-start));//260
}
浙公网安备 33010602011771号