我们接上篇,继续解密ForkJoinPool中的结果归并,其实很简单。
结果归并是是在计算任务完成后。我们还以上一篇帖子中的计算为例。
二、join()方法解密
上一篇最后,这时线程Thread[ForkJoinPool-1-worker-3,5,main]处理的任务【1,125】经过execTask等一系列方法后,调用computer方法,此时达到阈值,调用for循环开始计算结果,最终得到结果7875,并且设置。同理Thread[ForkJoinPool-1-worker-4,5,main]线程处理的任务【126,250】经过计算得到最后的结果23500。
这里要注意下,执行完各自计算任务的时候,在doExec()方法执行完成时,使用setCompletion(NORMAL);方法设置了完成状态(正常完成),表明该任务正常执行完成。
final void doExec() { if (status >= 0) { boolean completed; try { completed = exec(); } catch (Throwable rex) { setExceptionalCompletion(rex); return; } if (completed) setCompletion(NORMAL); // must be outside try block } } private int setCompletion(int completion) { for (int s;;) { if ((s = status) < 0) return s; if (UNSAFE.compareAndSwapInt(this, statusOffset, s, completion)) { if (s != 0) synchronized (this) { notifyAll(); } return completion; } } }
当工作线程Thread[ForkJoinPool-1-worker-3,5,main]和Thread[ForkJoinPool-1-worker-4,5,main]将各自的计算任务完成后,等待在计算任务【1,125】和【126,250】进行join完成的工作线程Thread[ForkJoinPool-1-worker-2,5,main]可以开始进行join操作了。
执行左任务的join方法,我们需要看下join方法的源码。
public final V join() { if (doJoin() != NORMAL) return reportResult(); else return getRawResult(); }
在join方法的源码中,判断条件处使用了doJoin()方法,我们需要先看下它:
private int doJoin() { Thread t; ForkJoinWorkerThread w; int s; boolean completed; if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) { if ((s = status) < 0) return s; if ((w = (ForkJoinWorkerThread)t).unpushTask(this)) { try { completed = exec(); } catch (Throwable rex) { return setExceptionalCompletion(rex); } if (completed) return setCompletion(NORMAL); } return w.joinTask(this); } else return externalAwaitDone(); }
在doJoin()方法中,判断比较多。第一个判断if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread),因为当前线程肯定是工作线程Thread[ForkJoinPool-1-worker-2,5,main],所以这个条件成立。内层判断,if ((s = status) < 0),当前status是任务的当前状态,在开篇我们就说了,任务执行完成时使用CAS原子方法,设置了status为NORMAL(-1),所以,这里也是成立的,因此直接返回s=-1,也就是doJoin()方法返回了-1。
回到Join方法中,if (doJoin() != NORMAL)这个条件就不成立了。因此return getRawResult();
我们看下getRawResult()方法,它就一行代码,返回计算结果result。
public final V getRawResult() { return result; }
因此工作线程left.join返回了7875,right.join返回了23500。因此工作线程Thread[ForkJoinPool-1-worker-2,5,main]返回的computer结果就是7875+23500=31375。
其他分支的流程处理方式一样,我们不再赘述。
最后说一句,其实写博客是件很费事的事情,读源码更是件费力的事情。
学习源码,是为了让自己理解的更透彻,而不是听别人去说,这个东西怎样怎样。
从一开始的排斥源码,慢慢的去学习设计者的想法,对自己的能力也是一种极大的提升。
相关推荐
Fork/Join框架是Java7引入的一种用于并行任务执行的框架,它允许将复杂任务拆分成多个子任务,并行执行,然后通过join操作将结果聚合。Fork/Join框架特别适合处理可以递归拆分的计算密集型任务,比如大数据集的搜索...
Java并发Fork-Join框架原理是Java7中提供的一种并行执行任务的框架,旨在提高程序的执行效率和性能。该框架的核心思想是将大任务分割成若干个小任务,并将其分配给不同的线程执行,以充分利用多核CPU的计算能力。 ...
ForkJoin并发框架是Java 7引入的一种高效并行计算框架,它基于分而治之(Divide and Conquer)的策略,适用于处理大量可分割的任务。这个框架的核心类是`ForkJoinPool`和`ForkJoinTask`,它们为开发者提供了创建和...
ForkJoinPool 线程泄漏 我的输出: Iteration 0: 3 threads Iteration 111: 118 threads Iteration 222: 229 threads Iteration 333: 340 threads Iteration 444: 451 threads Iteration 555: 562 threads ...
张孝祥Java多线程与并发库高级应用学习笔记,很经典的学习多线程和并发的资料。张孝祥Java多线程讲义笔记由张孝祥亲自整理,很实用的。
ForkJoin框架 是Java 7中引入的,旨在进一步提高并发程序的性能。它使用了一种称为“工作窃取”的算法,允许线程动态地重分配任务。ForkJoin的核心思想是将大任务分解为更小的任务,然后并行处理这些任务,最后合并...
Java多线程编程中的ForkJoinPool实例详解是Java 7中引入的一种高效的并发编程框架。ForkJoinPool是ExecutorService接口的实现,它管理工作窃取算法(Work-Stealing Algorithm)实现高效的任务执行和线程管理。 ...
java多线程与高并发java多线程与高并发java多线程与高并发
《Java多线程编程实战指南-核心篇》是一本深入探讨Java并发编程的书籍,旨在帮助读者掌握在Java环境中创建、管理和同步线程的核心技术。Java的多线程能力是其强大之处,使得开发者能够在同一时间执行多个任务,提高...
ForkJoin框架是Java并发编程中的一个重要工具,它基于分治策略,旨在高效处理大量数据。框架的核心思想是将一个大型任务分解成多个小型任务,然后通过并行执行这些子任务来提高处理效率。ForkJoin框架在Hadoop ...
### Java多线程与并发库高级应用 #### 一、Java多线程基础 在深入探讨Java多线程与并发库的高级应用之前,我们首先需要回顾一下Java多线程的基础概念和技术要点。 ##### 1.1 线程的概念 在计算机科学中,线程是...
Java中的ForkJoinPool是Java 7引入的一种新的线程池实现,它是为了解决大量并行计算场景下的效率问题而设计的。ForkJoinPool的设计理念基于分治策略(Divide and Conquer),适用于那些可以拆分成多个子任务的任务,...
Java多线程与并发是Java开发中的重要领域,尤其在现代高性能应用中,对多核处理器的充分利用和高效系统设计离不开并发技术。本主题主要基于《Java多线程编程核心技术》和《Java+7并发编程实战手册》两本书籍的核心...
Java ForkJoin框架是Java 1.7后提供的一种多线并发处理框架,主要思想是分而治之,将复杂的计算按照设定的阈值进行分解成多个计算,然后将各个计算结果进行汇总。ForkJoin框架的使用可以提高数据的计算速度,但需要...
Fork/Join框架是Java并发库中的一部分,自Java 7开始引入,它为开发者提供了一种高效的处理大规模计算任务的方法。这个框架基于分治策略,将大任务分解成若干小任务,然后并行执行这些小任务,最后再将结果合并。...
ForkJoin框架自Java 7引入,它为处理大型任务提供了一种分解成多个子任务并行执行的机制,然后合并子任务的结果。这种机制特别适合处理可以被分解的问题,例如计算、搜索等。 首先,让我们回顾一下传统的并发实现...
### 张孝祥Java多线程与并发库高级应用笔记概览 #### 一、Java多线程技术的重要性与挑战 Java线程技术是软件工程领域不可或缺的一部分,尤其在底层编程、Android应用开发以及游戏开发中,其重要性不言而喻。然而,...
在Java中,Fork/Join框架主要由`ForkJoinPool`线程池和`ForkJoinTask`任务类组成。 1. `ForkJoinPool`:这是Fork/Join框架的工作线程池。它维护着一组工作线程,用于执行`ForkJoinTask`。线程池中的每个工作线程都...
Java多线程实战精讲是Java开发者必备的技能之一,特别是在处理高并发场景时,它的重要性不言而喻。本文将深入探讨Java多线程的相关知识点,帮助你全面理解并掌握这一核心概念。 1. **线程基础** - **线程定义**:...