并发编程-07 ForkJoin分治

Java并发编程面试7:Fork/Join��架-ForkJoinPool和RecursiveTask 是 Fork/Join 框架的核心,它是一个专门为了执行任务而设计的线程池。这个线程池利用了工作窃取算法(work-stealing algorithm)来提高CPU的利用率和减少线程间的竞争。工作原理在中,每个参与的线程都维护着一个双端队列(deque),用来存放任务。当一个线程的队列为空时,它可以从其他线程的队列的末尾“窃取”一个任务来执行。这种策略减少了线程间的交互,提高了效率,尤其是当有大量小任务需要执行时。主要方法:同步执行指定的任务,并返回结果。> task):异步执行指定的任务。 阅读详情

ForkJoin工作原理

ForkJoin框架时对线程池普通线程池的补充。我们通常在使用线程池时,会有哪些痛点?

  • 无法对大任务进行拆分,单个任务只能交个单个线程执行
  • 当阻塞队列中有积压时,工作线程从队列中获取任务会存在竞争

本篇文章就来研究Doug Lea是如何巧妙利用分治思想解决上述问题的。在开始看ForkJoin前,需要先对线程池线程数和死锁有些认识,否则啃完ForkJoin框架,也用不好它。

1、如何设计线程池的线程数?

通常我们会用如何方式,自定义线程池,核心线程、非核心线程、非核心线程的等待时间、阻塞队列等。那么线程数如何取值更合理的?

new ThreadPoolExecutor(nThreads, nThreads,
                              0L, TimeUnit.MILLISECONDS,
                              new LinkedBlockingQueue<Runnable>());
1.1 CPU密集型的任务
  • 主要任务类型:加密、解密、压缩、计算等计算密集型任务
  • 特点:计算压力大,CPU消耗大
  • 最佳线程数:CPU核心数的1-2倍
  • 原因:CPU密集型任务,主要耗时在计算上。线程需要充分利用CPU持续的完成大量计算任务,这时如果线程数量过多反而会因频繁的上下文切换,而造成性能下降。
1.2 IO密集型的计算
  • 主要任务类型:数据库读写IO、网络IO、磁盘文件读写IO等网络通信任务
  • 特点:CPU压力小,IO等待耗时长
  • 最佳线程数:CPU核心数的N倍
  • 原因:CPU计算压力小,更多的时间消耗在IO的阻塞上,频繁的切换上下文,能减少工作队列的等待耗时。
1.3 从业务实际角度考量
  • 考虑业务的并发量、每秒可以处理的请求数、阻塞队列长度兜底保证浪涌情况下,不丢失请求
  • 想要获取更准确线程数,需要经过压测来检验,结合实际情况,合理利用资源。

2、如何看待线程死锁、活锁

2.1 死锁问题
2.1.1 什么是死锁?

面试官:什么是死锁?(回答我,我就录取你!)

答:你录取我,我就告诉你什么是死锁!

死锁用生活中的道理表述 :双方继续执行下去的前提是,对方先满足自己的要求。(线程互相等待)

2.1.2 怎么解决死锁问题?

锁成立的必要条件:

  • 互斥条件[AQS中的信号量state]

  • 占有且等待[排它锁占有时,阻塞]

  • 不可强行占有[当线程已获取到锁,在它释放前,其他线程无法cas占有]

  • 循环等待条件(打破等待条件即可解决死锁)

2.1.3 死锁问题的场景
  • 线程间相互等待导致的死锁。

    打破循环等待条件即可

    案例

  • 线程饥饿,线程池瞬间满载阻塞,且没有中断策略。导致线程池无线程可用导致的死锁。ForkJoin如何拿来做阻塞类型任务,当线程饥饿时,极有可能导致该类问题。

    案例

2.1.4 活锁问题

线程A、B相互谦让,A发现B需要执行,将执行权交给B;线程B发现线程A需要执行,将执行权交给A,相互谦让,生成活锁。

案例

3、Fork/Join框架介绍

http://gee.cs.oswego.edu/dl/papers/fj.pdf Doug Lea 关于ForkJoin的论文

3.1 分治思想

思想比代码重要。充分利用多线程的优势,集中将庞大地、可拆分地任务进行fork(),分解到通过多个工作线程分别承担一部分任务,通过子线程的并行计算最终递归得到执行结果。
在这里插入图片描述

3.2 ForkJoinPool

3.2.1 构造方法

  • parallelism 线程池的并行数[控制线程工厂中线程个数]

    控制工作线程的数量,未设置则使用默认的Runtime.getRuntime().availableProcessors()核数

  • factory [负责工作线程创建的线程工厂]

    可是实现ForkJoinWorkerThreadFactory来自定义,默认DefaultForkJoinWorkerThreadFactory

  • handler[异常处理]

    UncaughtExceptionHandler运行时异常的处理器

  • asyncMode

    设置队列的工作模式:asyncMode ? FIFO_QUEUE : LIFO_QUEUE。相当于是否公平

public ForkJoinPool(int parallelism,
                    ForkJoinWorkerThreadFactory factory,
                    UncaughtExceptionHandler handler,
                    boolean asyncMode) {
    this(checkParallelism(parallelism),
         checkFactory(factory),
         handler,
         asyncMode ? FIFO_QUEUE : LIFO_QUEUE,
         "ForkJoinPool-" + nextPoolId() + "-worker-");
    checkPermission();
}

3.2.2 核心任务提交方法

返回值方法
提交异步执行voidexecute(ForkJoinTask task)
execute(Runnable task)
等待并获取结果Tinvoke(ForkJoinTask task)
提交执行获取Future结果ForkJoinTasksubmit(ForkJoinTask task)
submit(Callable task)
submit(Runnable task)
submit(Runnable task, T result)
3.3 ForkJoinTask

ForkJoinTask是ForkJoinPool的核心之一,它是任务的实际载体,定义了任务执行时的具体逻辑和拆分逻辑。ForkJoinTask继承了Future接口,所以也可以将其看作是轻量级的Future。

3.3.1 ForkJoinTask核心方法

  • fork() [查分任务提交到线程池]

    fork()方法用于向当前任务所运行的线程池中提交任务。如果当前线程是ForkJoinWorkerThread类型,将会放入该线程的工作队列,否则放入common线程池的工作队列中。

  • join() [阻塞等待任务结果]

    join()方法用于获取任务的执行结果。调用join()时,将阻塞当前线程直到对应的子任务完成运行并返回结果

3.3.2 常用实现类

  • RecursiveAction

    用于递归执行但不需要返回结果的任务

  • RecursiveTask

    用于递归执行需要返回结果的任务。

  • CountedCompleter

    在任务完成执行后会触发执行一个自定义的钩子函数

3.4 ForkJoinWorkerThread

由ForkJoinWorkerThreadFactory工厂创建的工作线程,每个线程与ForkJoinPool.WorkQueue队列深度绑定

普通线程池的预热

//核心线程的预热
ExecutorService executors = Executors.newFixedThreadPool(10);
((ThreadPoolExecutor)executors).prestartAllCoreThreads();

4、Fork/Join原理及使用场景

4.1 核心使用场景(递归计算返回结果)

使用场景:大量CPU计算场景。

案例:

public class ForkJoinTest {
    final static ForkJoinPool.ForkJoinWorkerThreadFactory factory = new ForkJoinPool.ForkJoinWorkerThreadFactory() {
        @Override
        public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
            final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
            worker.setName("My-ForkJoin-thread-"+ worker.getPoolIndex());
            return worker;
        }
    };
    static ExecutorService executorService = Executors.newFixedThreadPool(10);
    public static void main(String[] args) throws Exception {
        int arr[] = Utils.buildRandomIntArray(100000000);

        //为避免cpu缓存,先计算forkJoin分治算法
        testForkJoinSub(8,arr);
        //单线程耗时
        testForkJoinSub(arr);
        //并行流算法
        testParallelSum(arr);
    }

    /**
     * forkJoin算法
     *
     * @param parallelism
     * @param arr
     * @throws Exception
     */
    public static void testForkJoinSub(int parallelism,int arr[]) throws Exception {
        //Runtime.getRuntime().availableProcessors()  forkJoin默认并行数
        ForkJoinPool forkJoinPool = new ForkJoinPool(parallelism,factory,null,false);
        Instant now = Instant.now();
        RecursiveTask task = new CalcTask(arr,0,arr.length);

        //提交任务
        ForkJoinTask<Long> submit = forkJoinPool.submit(task);

        Long aLong = submit.get();

        System.out.println("forkJoin sum="+aLong);
        System.out.println("forkJoin 耗时:"+ Duration.between(now,Instant.now()).toMillis());
    }

    /**
     * 单线程计算结果
     * @param arr
     */
    public static void testForkJoinSub(int arr[]){
        Long sum = 0L;
        Instant now = Instant.now();
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        System.out.println("单线程 sum="+sum);
        System.out.println("单线程 耗时:"+ Duration.between(now,Instant.now()).toMillis());
    }

    /**
     * stream流
     * @param arr
     */
    public static void testParallelSum(int arr[]){
        Instant now = Instant.now();
        Long sum = IntStream.of(arr).asLongStream().sum();
        System.out.println("stream流 sum="+sum);
        System.out.println("stream流 耗时:"+ Duration.between(now,Instant.now()).toMillis());
    }
}

单线程、forkJoin、并行流计算的结果及耗时对比:

执行的结果
#print result
forkJoin sum=49951294336
forkJoin 耗时:48
单线程 sum=49951294336
单线程 耗时:493
stream流 sum=49951294336
stream流 耗时:72

Process finished with exit code 0
public class CalcTask extends RecursiveTask<Long> {
    // 任务拆分最小阈值
    static final int SEQUENTIAL_THRESHOLD = 10000000;

    int low;
    int high;
    int[] array;

    CalcTask(int[] arr, int lo, int hi) {
        array = arr;
        low = lo;
        high = hi;
    }

    @Override
    protected Long compute() {

        //当任务拆分到小于等于阀值时开始求和
        if (high - low <= SEQUENTIAL_THRESHOLD) {

            long sum = 0;
            for (int i = low; i < high; ++i) {
                sum += array[i];
            }
            return sum;
        } else {  // 任务过大继续拆分
            int mid = low + (high - low) / 2;
            CalcTask left = new CalcTask(array, low, mid);
            CalcTask right = new CalcTask(array, mid, high);
            // 提交任务
            left.fork();
            right.fork();
            //获取任务的执行结果,将阻塞当前线程直到对应的子任务完成运行并返回结果
            long rightAns = right.join();
            long leftAns = left.join();
            return leftAns + rightAns;
        }
    }
}
4.2 任务窃取

每个workQueue为了方便窃取任务,都是双端队列。
在这里插入图片描述

4.3 内外部提交任务流程图

在这里插入图片描述

5、思考

5.1 并流行的坑

ForkJoinTask在执行fork方法时可见,外部提交的任务由ForkJoinPool.common.externalPush(this)来执行

public final ForkJoinTask<V> fork() {
    Thread t;
    if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread)
        ((ForkJoinWorkerThread)t).workQueue.push(this);
    else
        ForkJoinPool.common.externalPush(this);
    return this;
}

在这里插入图片描述
在这里插入图片描述
因此,如果forkjoin出现阻塞任务时,极有可能出现在开头中描述的因饥饿或阻塞的死锁。

ForkJoin处理千万条数据的多线程处理 这次我的任务是一次插入几千条用户操作数据,在虽然在Linux环境下执行影响不大,但是但window环境下非常的慢,甚至超过请求响应时间,然后我就用ForkJoin处理多数据操作问题,将大任务分为小任务来执行 Fork/Join框架是Java 7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。Fork/Join框架要完成两件事情: ... 阅读详情

相关推荐

并发编程之:ForkJoin-​分治法解决问题的思路,使用场景全解析

目录 分治法 解决问题的思路 使用场景 ForkJoin并行处理框架 ForkJoin框架实现 工作窃取算法 优点 缺点 在JDK1.7中引入了一种新的Fork/Join线程池,它可以将一个大的任务拆分成多个小的任务并行执行并汇总执行结果。 Fork/Join采用的是分而治之的基本思想,分而治之就是将一个复杂的任务,按照规定的阈值划分成多个简单的小任务,然后将这些小任务的结果再进行汇总返回,得到最终的任务。 分治法 分治法是计算机领域常用的算法中的其中一个,主要思想就是将将一个规

qq_46388795的博客 1329

常见锁策略、锁优化及死锁

Ⅰ常见的锁策略 (1)乐观锁和悲观锁 乐观锁:乐观锁假设认为数据一般情况下不会产生并发冲突,所以在数据进行提交更新的时候,才会正式对数据是否产生并发冲突进行检测(可以使用版本号机制和CAS算法实现检测),如果发现并发冲突,则返回用户错误的信息。 悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。 悲观锁的问题:总是需要竞争锁,进而导致发生线程切换,挂起其他线程;所以性能不高。 乐观锁的问题:并不总是能处理所有问题,所以会

长不大的大灰狼 1441

Java 线程池 ForkJoinPool(一)

线程管理器(ThreadPool):用于创建并管理线程池,包括创建线程池,销毁线程池,添加新任务。工作线程(PoolWorker):线程池中的线程,在没有任务时处于等待状态,可以循环的执行任务;任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它注意规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;任务队列(taskQueue):用于存放没有处理的任务,提供一种缓冲机制。

gmHappy 1256

JUC五-ForkJoin,JMM和volatile,CAS,自旋锁,死锁

上面例子体现的实际就是可见性,它保证的是在多个线程之间,一个线程对volatile 变量的修改对另一个线程可见, 不能保证原子性,仅用在一个写线程,多个读线程的情况。,编译器重排序,就是在编译过程中,编译器根据上下文分析对指令进行重排序,目的是减少CPU和内存的交互,重排序之后尽可能保证CPU从寄存器或缓存行中读取数据。(3)请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。所以两次操作值还是1,肯定就少了。

beginner的博客 391

并发编程系列之什么是ForkJoin框架?

并发编程系列之什么是ForkJoin框架?ForkJoin框架是java的JUC包里提供的,用于处理一些比较繁重的任务,会将这个大任务分为多个小任务,多个小任务处理完成后会将结果汇总给Result,体现的是一种“分而治之”的思想。第一步,拆分fork任务,将大任务分为多个小任务;第二步,归并join,会将小任务的处理结果进行归并为一个结果。

Nicky's blog 1547

STM32CubeMX定时器进阶玩法:用编码器模式实现电机转速测量(附避坑清单)

本文详细介绍了如何使用STM32CubeMX配置定时器的编码器模式实现电机转速测量,包括硬件连接、CubeMX配置关键步骤、转速计算算法及常见问题解决方案。特别针对工业控制和机器人开发中的高精度需求,提供了实用的避坑清单和优化技巧,帮助开发者高效完成项目。

joy55的博客 203

并发编程—ForkJoin分治思想

一、什么是ForkJoin ForkJoin框架包含ForkJoinTask、ForkJoinWorkerThread、ForkJoinPool 和若干ForkJoinTask的子类,核心在于分治和 工作窍取,最大程度利用线程池中的工作线程,避免忙的忙死,饿的饿死。 文章重点讲解:ForkJoinPool、ForkJoinTask的使用 ForkJoinPool ForkJoinPool 是JDK7引入的线程池,核心思想是将一个大的任务拆分成n个小任务(即fork),然后在将多个小任务处..

祝我飞黄腾达 4056

Flutter + shorebird 热更新+自定义cdn下载

本文介绍了如何优化Flutter热更新方案Shorebird在国内网络环境下的使用体验。Shorebird默认使用海外CDN存在下载慢、连接不稳定等问题,建议将补丁包上传至国内CDN(如阿里云OSS)。文章详细讲解了Shorebird环境配置、项目集成、构建发布流程,并重点说明了如何修改客户端代码实现自定义补丁下载逻辑。通过替换默认下载器,将补丁下载地址指向国内CDN,可显著提升下载速度和稳定性。这种方案既保留了Shorebird的热更新能力,又解决了国内网络环境下的痛点,适合国内企业部署使用。

sir_Hu的博客 769

【高并发】什么是ForkJoin?看这一篇就够了!

在JDK中,提供了这样一种功能:它能够将复杂的逻辑拆分成一个个简单的逻辑来并行执行,待每个并行执行的逻辑执行完成后,再将各个结果进行汇总,得出最终的结果数据。有点像Hadoop中的MapReduce。 ForkJoin是由JDK1.7之后提供的多线程并发处理框架。ForkJoin框架的基本思想是分而治之。什么是分而治之?分而治之就是将一个复杂的计算,按照设定的阈值分解成多个计算,然后将各个计算结果进行汇总。相应的,ForkJoin将复杂的计算当做一个任务,而分解的多个计算则是当做一个个

冰河的专栏 2147

高匿反爬实战:Python打造无痕爬虫,规避风控系统追踪

网络层匿踪:核心是使用住宅IP代理池,按真实用户IP画像匹配,控制请求频率;协议层匿踪:动态生成请求头(每次都不同),参数添加随机噪声,避免规律化;行为层匿踪:模拟人类的非规律行为(贝塞尔轨迹、随机停顿、非精准点击);设备层匿踪:伪造Canvas/WebGL指纹,禁用webdriver标识,每次请求更换指纹;核心原则:无痕爬虫的本质是“无限接近真实用户”,所有维度都要消除爬虫特征,而非单一维度伪装。打造真正的无痕爬虫需要全维度的匿踪策略,单一维度的伪装极易被高级风控系统识别。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 2642

Vue 网络处理 - axios 异步请求的使用,请求响应拦截器(最佳实践)

axios 用来在前端页面发起一个异步请求,请求之后页面不动,响应回来刷新局部.1.为什么不使用 ajax 呢?官方:在 jQuery 中推荐使用 ajax 技术, Vue 里面不推荐使用 jQuery 框架,因此 Vue 更推荐使用 axiox 异步请求库(axios并不是 vue 官方库).2.axios 特性可以从浏览器中创建 XMLHttpRequests可以从 node.js 中创建 http 请求.支持 Promise API.支持拦截请求和响应.转换请求数据和响应数据.

CYK_byte的博客 1万+

Java并发编程 - 分支合并ForkJoin

ForkJoin框架提供了一种优雅的方式来处理并行任务,尤其是那些可以自然地分解为子任务的问题。通过使用和,可以很容易地实现并行计算,并充分利用多核处理器的优势。在设计并行算法时,ForkJoin框架是一个非常有用的工具。

qq_33240556的博客 1102

今日指数项目之实时流数据采集【六】

实时数据采集代码

Maynor的博客 2146

什么是ForkJoin?看这一篇就能掌握!

ForkJoin是由JDK1.7之后提供的多线程并发处理框架。

华为云官方博客 1085

组合预测 | Python实现LSTM-XGBoost长短期记忆网络组合极限梯度提升树股票价格预测

组合预测 | Python实现LSTM-XGBoost长短期记忆网络和极限梯度提升树股票价格预测

机器学习之心的博客,关注并私信文章链接,获取对应文章源码和数据。 2353

地统计插值学习心得(一)

(创建地统计图层工具用于根据现有的地统计图层或者地统计模型来创建包含新要素数据集的地统计图层,也就是使用构建好的地统计模型用到新的数据集中)这表明,远离极值的区域预测不受极值的影响,并且还表明,包括极值会导致钼元素浓度高的区域周围的预测明显变高。通常,我们使用同一个数据集进行建模和预测,但是在实际插值过程中,这两步的数据可以是不同的,这就是处理极值的诀窍。如果你的数据集有无法忽略的极值时(比如这些钼元素浓度),一种常见的方法是首先显式移除极值进行建模,然后在预测中使用整个数据集(包括极值)。

JData_Engineer的博客 286

并发编程十五:线程池任务类型和ForkJoin实战详解

文章目录线程池任务类型和ForkJoin实战详解线程池任务类型分治算法Fork/Join框架介绍Fork/Join使用Fork/Join实战案例RecursiveAction类型RecursiveTask类型CountedCompleterForkJoin原理分析ForkJoin流程图 线程池任务类型和ForkJoin实战详解 线程池任务类型 我们调整线程池中的线程数量的最主要的目的是为了充分并合理地使用CPU和内存等资源,从而最大限度地提高程序的性能。在实际工作中,我们需要根据任务类型的不同选择对应的策略

admin522043032的博客 1395

FPGA控制AD5754实现模数转换Verilog代码与测试激励

本文提供了使用FPGA控制AD5754芯片实现数字信号转模拟信号的Verilog代码和测试激励。AD5754芯片简介:AD5754是一款16位数字信号转模拟信号的芯片。通信方式:FPGA与AD5754之间通过SPI接口进行通信,SPI时钟clk的最大频率为30MHz。模拟输出:AD5754提供了四路模拟输出。工作方式:当前AD5754采用单极性工作方式。指令刷新:根据现有理解,同轴的速度和电流指令应同时刷新。利用LDAC引脚控制模拟信号的刷新,但需实际验证。CLR信号验证。

whm128的博客 246

并发编程系列-分而治之思想Forkjoin

ForkJoinPool支持任务窃取机制,能够让所有线程的工作量基本均衡,不会出现有的线程很忙,而有的线程很闲的状况,所以性能很好。在这个计算框架中,Fork代表任务的分解,而Join代表结果的合并。这两部分的关系类似于ThreadPoolExecutor和Runnable之间的关系,都是用于提交任务到线程池的,只不过分治任务有自己独特的类型ForkJoinTask。在这个分治任务模型里,任务和分解后的子任务具有相似性,这种相似性往往体现在任务和子任务的算法是相同的,但是计算的数据规模是不同的。

1257

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

【高并发】什么是 ForkJoin?看这一篇就够了!

Java 1.7 引入了一种新的并发框架—— Fork/Join Framework,主要用于实现“分而治之”的算法,特别是分治之后递归调用的函数。ForkJoin 框架的本质是一个用于并行执行任务的框架, 能够把一个大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务的计算结果。在 Java 中,ForkJoin 框架与 ThreadPool 共存,并不是要替换 ThreadPool其实,在 Java 8 中引入的并行流计算,内部就是采用的 ForkJoinPool 来实现的。

m0_67698950的博客 193

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

分治思想ForkJoin原理分析

CPU密集型任务的特点就是计算密集,对CPU的依赖相当高,对于这样的任务线程分配的最佳实践就是CPU核心数的2倍,如果设置过多会导致线程上下文切换十分频繁。IO密集型任务属于IO频繁,例如数据库的访问、文件访问、网络传输等,这些操作不会耽误CPU的资源但是会消耗IO资源,任务的执行时长较长。这样的任务线程分配最佳实践就是多余CPU的核心数好几倍。但是对于IO密集型的任务需要压测来进行最优的分配。分而治之的指导思想就是将一个规模为N的问题进行分解拆分为K个小的子问题,这些子问题相互独立并且原理性质相同,甚至子

Minor的Java技术博客 316

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

「高并发」什么是ForkJoin?看这一篇就够了

写在前面 在JDK中,提供了这样一种功能:它能够将复杂的逻辑拆分成一个个简单的逻辑来并行执行,待每个并行执行的逻辑执行完成后,再将各个结果进行汇总,得出最终的结果数据。有点像Hadoop中的MapReduce。 ForkJoin是由JDK1.7之后提供的多线程并发处理框架。ForkJoin框架的基本思想是分而治之。什么是分而治之?分而治之就是将一个复杂的计算,按照设定的阈值分解成多个计算,然后将各个计算结果进行汇总。相应的,ForkJoin将复杂的计算当做一个任务,而分解的多个计算则是当做一个个子任务

m0_50180963的博客 479

深入解析Java并发编程核心:ForkJoin工作窃取算法与双端队列实现

在当今计算密集型应用日益普及的背景下,Java并发编程已成为开发者必须掌握的核心技能。多核处理器的普及使得传统单线程程序无法充分利用硬件资源,而并发编程通过将任务分解为可并行执行的单元,显著提升了系统吞吐量和响应速度。Java从早期版本就提供了丰富的并发编程工具,包括Thread类、synchronized关键字以及java.util.concurrent包中的高级并发组件,这些工具共同构成了Java强大的并发生态系统。

zuiyuelong的博客 915

并发编程之ForkJoin和线程的并发工具类

并发编程之线程的并发工具类 文章目录并发编程之线程的并发工具类ForkJoin并发工具类CountDownLatchCyclicBarrierSemaphoreExchangeCallable、Future和FutureTask相关链接公众号参考 ForkJoin 分而治之: ForkJoin 在处理 分而治之的问题 时非常的有用。 十大计算机经典算法:快速排序、堆排序、归并排序、二分查找、线性查找、 深度优先、广度优先、Dijkstra、动态规划、朴素贝叶斯分类,属于分而治之的有3个,快速排序、归并排序

chen 287

【并发编程】聊聊forkJoin的原理和最佳实践

【并发编程】聊聊forkJoin的原理和最佳实践

芝兰生于深谷,不以无人而不芳 907
上一篇: 并发编程-06 BlockingQueue及应用场景详解
下一篇: 并发编程-08 Future&CompletableFuture用法
旧梦昂志
博客等级 码龄7年 3724粉丝 68原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旧梦昂志

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值