本文主要介绍“如何使用Java JUC多线程分叉连接池”。在日常操作中,相信很多人对于如何使用Java JUC多线程Fork Join Pool都有疑问。边肖查阅了各种资料,整理出简单易用的操作方法,希望能帮你解答“如何使用Java JUC多线程Fork Join Pool”的疑惑!接下来,请和边肖一起学习!
在工作中,当我们计算一个大值加上一个大值等等,此时计算机在串行计算中消耗了大量的CPU,效率也很低。
这时候我们可以选择多线程分支合并使用多个线程进行计算,然后将最后一个线程的结果合并成最终的结果。
ForkJoinPool分支/合并框架工作偷换Fork/Join框架:如果需要,将一个大任务分叉成几个小任务(当不能再次拆解时),然后在Join中汇总每个小任务的操作结果。
图:
分叉/连接框架和线程池的区别
采用“偷工减料”模式:执行新任务时,可以将其拆分成更小的任务,将小任务添加到线程队列中,然后从随机线程的队列中偷出一个放入自己的队列中。
与线程池的一般实现相比,fork/join框架的优势在于处理其中包含的任务的方式。在通用线程池中,如果线程正在执行的任务由于某种原因无法继续运行,那么线程将处于等待状态。然而,在fork/join框架的实现中,如果一个子问题因为等待另一个子问题的完成而无法继续运行。然后处理该子问题的线程会主动找到其他尚未运行的子问题来执行。这种方式减少了线程的等待时间,提高了性能。
话不多说,看看代码:
package com . at xiaodei . javajuc . jucdemo;import org . JUnit . test;import Java . time . duration;import Java . time . instant;import Java . util . concurrent . forkjoinpool;import Java . util . concurrent . forkjointask;import Java . util . concurrent . recursivetask;import Java . util . stream . longstream;/* * * @ authorwangmang * @ date 2020/9/23 * ForkJoinpool分支/合并框架工作窃取*前言:当我们在计算一个大值加一个大值时,等等。此时计算机在串行计算中消耗大量CPU,效率较低。这时我们可以选择*多线程分支合并,使用多线程进行计算。然后将最后几个线程的结果合并成最终结果* * */publicclass testforkjoinpool线程分支合并{ publicstattcvoitmain(string[]args){//1.8特征获取计算instant start=instant . now();ForkJoinPoolpool=new forkjoinpool();ForkJoinTaskLongtask=new forkjoinsumcalculate(0L,5000000000 l);long sum=pool . invoke(task);system . out . println(sum);(=NationalBureauofStandards)国家标准局
p; Instant end = Instant.now(); System.out.println("耗费时间为:" + Duration.between(start, end).toMillis());//166-1996-10590 } @Test public void test1(){ Instant start = Instant.now(); long sum = 0L; for (long i = 0L; i <= 50000000000L; i++) { sum += i; } System.out.println(sum); Instant end = Instant.now(); System.out.println("耗费时间为:" + Duration.between(start, end).toMillis());//35-3142-15704 } //java8 新特性 @Test public void test2(){ Instant start = Instant.now(); Long sum = LongStream.rangeClosed(0L, 50000000000L) .parallel() .reduce(0L, Long::sum); System.out.println(sum); Instant end = Instant.now(); System.out.println("耗费时间为:" + Duration.between(start, end).toMillis());//1536-8118 }}// 继承 RecursiveTask<返回类型> 实现compute方法完成分支合并class ForkJoinSumCalculate extends RecursiveTask<Long> { private static final long serialVersionUID = -259195479995561737L; private long start; private long end; private static final long THURSHOLD = 10000L; //临界值 public ForkJoinSumCalculate(long start, long end) { this.start = start; this.end = end; } @Override protected Long compute() { long length = end - start; if(length <= THURSHOLD){ long sum = 0L; for (long i = start; i <= end; i++) { sum += i; } return sum; }else{ long middle = (start + end) / 2; ForkJoinSumCalculate left = new ForkJoinSumCalculate(start, middle); //进行拆分(这里看不到到底在哪个里面计算的值呢?好好想,好看, // 上面的概念,(拆到不可再拆时,也就是当前length小于等于10000L的时候进行计算)),同时压入线程队列 left.fork(); ForkJoinSumCalculate right = new ForkJoinSumCalculate(middle+1, end); right.fork(); //进行拆分,同时压入线程队列 return left.join() + right.join(); } }}
运行代码,完成总结:
-
在进行小数值计算的时候,效率 java8新特性Stream<for迭代器<ForkJoinPool 分支合并
-
在进行大数值特别大的计算的时候,效率 ForkJoinPool 分支合并< java8新特性Stream<for迭代器
大数值 ForkJoinPool 分支合并效率最好,Steam还行,for迭代器特别卡,执行半分钟
到此,关于“Java JUC多线程的Fork Join Pool怎么使用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/115169.html