JUC练习13——forkJoin

什么是forkjoin?

就是将单线程下的一个大任务,拆分成多个小任务,将多个小任务派给其它线程执行,最终将所有执行的结果汇总得到最终的结果

本质是:将单线程的大任务转成多线程的小任务,所以对于大任务有效率上的提高。

例如线程1上的任务执行forkJoin后分为了四个任务,这四个任务放在双端队列中等待线程1执行。

另外一个线程2刚刚完成了其它的任务此时处于空闲状态,在forkjoin下 它会执行工作窃取,去

线程1的双端队列中,从另一个端窃取线程进行执行。

JUC练习13——forkJoin

 

 2,java中如何使用forkjoin

  1. 继承类 ForkJoinTask<V>的子类编写一个任务类:RecursiveAction为递归事件无返回值,或者RecursiveTask为递归任务有返回值
  2. 实现对应的抽象方法compute
  3. 将实例化的任务对象交给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
    }

  

上一篇:[经验总结]error: no match for ‘operator>’ (operand types are ‘const *’ and ‘const *’) { return _


下一篇:力扣剑指offer第13天 栈