forkJoin提交任务执行流程
设置 并行度 = 1 的线程池分析CountTask的执行过程(1+2+3+4 -> 1+2 and 3+4)
执行过程中会出现三个task,分别设置为 task1 -> task2 + task3
任务1
此时内部的工作队列数组workQueues == null
(1) 创建workQueues,此时数组中所有元素都为null, 设置runState = started
(2) 创建工作队列workQueue,在ws的索引值为 k = r & m & SQMASK
r 表示线程的探针哈希值:作用是哈希线程,将线程和数组中的不用元素对应起来,尽量避免线程争用同一数组元素。
探针哈希值和 map 里使用的哈希值的区别是,当线程发生数组元素争用后,可以改变线程的探针哈希值,让线程去使用另一个数组元素。
m 表示数组的长度 - 1
SQMASK = 0xffff (最大的索引值)
(3)将forkJoinTask提交到该工作队列中
(4)创建 or 唤醒 一个worker线程执行任务
(5)创建forkJoinWorkerThread线程,调用start方法
工厂模式创建线程,该线程有两个重要属性
this.pool = pool;
this.workQueue = pool.registerWorker(this);
线程池注册workerThread线程
(1)创建工作队列
(2)设置在队列数组中的索引值,保证在奇数位
任务2
如果当前线程是ForkJoinWorkerThread,将task放到双端队列的头部
任务3