面试官: Fork/Join 有了解过吗?说说看(含源码分析)

前言

目前正在出一个Java多线程专题长期系列教程,从入门到进阶含源码解读, 篇幅会较多, 喜欢的话,给个关注❤️ ~

本节给大家介绍一个同样实现了ExecutorService接口的多线程处理器Fork/Join框架,一起来看下吧~

Fork/Join

首先从字面意思讲,fork有分发的意思,join有聚合的意思,所以大胆猜测一下,fork就是把一个大的任务拆分成诸多小的任务,join就是将最终的结果结合起来。

下面我们通过一个累加的demo快速的认识一下它,这里尽量的简单,让大家好理解 ~

private int doJoin() {
    int s; Thread t; ForkJoinWorkerThread wt; ForkJoinPool.WorkQueue w;
    // 先判断任务是否执行完毕,执行完毕直接返回结果(执行状态)
    return (s = status) < 0 ? s :
    // 如果没有执行完毕,先判断是否是ForkJoinWorkThread线程
        ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ?
        // 如果是,先判断任务是否处于工作队列顶端(意味着下一个就执行它)
        // tryUnpush()方法判断任务是否处于当前工作队列顶端,是返回true
        // doExec()方法执行任务
        (w = (wt = (ForkJoinWorkerThread)t).workQueue).
        // 如果是处于顶端并且任务执行完毕,返回结果
        tryUnpush(this) && (s = doExec()) < 0 ? s :
        // 如果不在顶端或者在顶端却没执行完毕,那就调用awitJoin()执行任务
        // awaitJoin():使用自旋使任务执行完成,返回结果
        wt.pool.awaitJoin(w, this0L) :
        // 如果不是ForkJoinWorkThread线程,执行externalAwaitDone()返回任务结果
        externalAwaitDone();
}

工作窃取算法

Fork/Join框架在处理任务时使用了工作窃取算法, 工作窃取算法指的是在多线程执行不同任务队列的过程中,某个线程执行完自己队列的任务后从其他线程的任务队列里窃取任务来执行。

当一个线程窃取另一个线程的时候,为了减少两个任务线程之间的竞争,我们通常使用「双端队列」来存储任务。被窃取的任务线程都从双端队列的「头部」进行任务执行,而窃取其他任务的线程从双端队列的「尾部」执行任务。

另外,当一个线程在窃取任务时没有可用任务,就会进入「阻塞状态」以等待再次工作

结束语

本节主要讲解它的一个使用,有兴趣的同学可以继续看一下它的底层源码实现。下一节,给大家讲下Stream流式计算多线程处理,关注我,不迷路 ~

往期并发编程内容推荐

项目源码(源码已更新 欢迎star⭐️)

  • java-thread-all

  • 地址: https://github.com/qiuChengleiy/java-thread-all.git

推荐 SpringBoot & SpringCloud (源码已更新 欢迎star⭐️)


本篇文章来源于微信公众号: 程序员皮卡秋



微信扫描下方的二维码阅读本文

此作者没有提供个人介绍
最后更新于 2023-06-27