ReduceOps.evaluateParallel()
方法是其实现之一
@Override
public <P_IN> R evaluateParallel(PipelineHelper helper,
Spliterator<P_IN> spliterator) {
return new ReduceTask<>(this, helper, spliterator).invoke().get();
}
复制代码
主要做了两件事:
-
创建一个ReduceTask任务
-
任务调用invoke()执行
创建的逻辑没有额外的操作,就是将三个参数赋值到实例变量中。
invoke()是ForkJoinTask的方法,方法这里主要关注invoke()
方法的逻辑:
/**
-
Commences performing this task, awaits its completion if
-
necessary, and returns its result, or throws an (unchecked)
-
{@code RuntimeException} or {@code Error} if the underlying
-
computation did so.
-
@return the computed result
*/
public final V invoke() {
int s;
//执行任务
if ((s = doInvoke() & DONE_MASK) != NORMAL)
reportException(s);
// 这里放回的是最终结果
return getRawResult();
}
复制代码
/**
-
Implementation for invoke, quietlyInvoke.
-
@return status upon completion
*/
private int doInvoke() {
int s; Thread t; ForkJoinWorkerThread wt;
return (s = doExec()) < 0 ? s :
((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ?
(wt = (ForkJoinWorkerThread)t).pool.
awaitJoin(wt.workQueue, this, 0L) :
externalAwaitDone();
}
==> JDK代码为了性能,牺牲了可读性,这里整理下:
private int doInvoke() {
s = doExec();
if (s < 0) return s;
t = Thread.currentThread();
if (t instanceof ForkJoinWorkerThread) {
ForkJoinWorkerThread wt = (ForkJoinWorkerThread)t.pool();
return wt.awaitJoin(wt.workQueue,this,0L);
}
return externalAwaitDone();
}
复制代码
/**
-
If the pending count is nonzero, decrements the count;
-
otherwise invokes {@link #onCompletion(CountedCompleter)}
-
and then similarly tries to complete this task’s completer,
-
if one exists, else marks this task as complete.
*/
public final void tryComplte() {
CountedCompleter<?> a = this, s = a;
for (int c;😉 {
if ((c = a.pending) == 0) {
a.onCompletion(s);
if ((a = (s = a).completer) == null) {
s.quietlyComplete();
return;
}
}
else if (U.compareAndSwapInt(a, PENDING, c, c - 1))
return;
}
}
复制代码
在ReduceOps.onCompletion()
的重写方法中,如果是不是叶子节点,则合并两个子节点的结果:
@Override
public void onCompletion(CountedCompleter<?> caller) {
if (!isLeaf()) {
//如果不是叶子节点,将左右两个子节点的结果合并。
S leftResult = leftChild.getLocalResult();
leftResult.combine(rightChild.getLocalResult());
setLocalResult(leftResult);
}
// GC spliterator, left and right child
super.onCompletion(caller);
}
复制代码
关注里面3个方法:
-
isLeaf()
-
combine()
-
super.onCompletion()
isLeaf()判断是不是叶子节点,只有非叶子节点才有两个子节点,然后才能进行合并任务:
protected boolean isLeaf() {
return leftChild == null;
}
复制代码
节点在执行完后调用super.onCompletionc(caller)
方法, 字段设为null,为了gc
@Override
public void onCompletion(CountedCompleter<?> caller) {
spliterator = null;
leftChild = rightChild = null;
}
复制代码
终点看下combine()方法,这个方法的作用是将结果组合
@Override
public void combine(ReducingSink other) {
if (!other.empty)
accept(other.state);
}
// 将本类的state和参数t进行一次运算,由于t是另一个部分运算的结果
// 这里的作用就是两部分进行运算求出结果
@Override
public void accept(T t) {
if (empty) {
empty = false;
state = t;
} else {
state = operator.apply(state, t);
}
}
复制代码
apply(state,t)
运算的逻辑是使用者定义的,对应我们的示例即 .reduce((x, y) -> x + y + 10)
Java面试核心知识点笔记
其中囊括了JVM、锁、并发、Java反射、Spring原理、微服务、Zookeeper、数据库、数据结构等大量知识点。
Java中高级面试高频考点整理
最后分享Java进阶学习及面试必备的视频教学
x, y) -> x + y + 10)`
Java面试核心知识点笔记
其中囊括了JVM、锁、并发、Java反射、Spring原理、微服务、Zookeeper、数据库、数据结构等大量知识点。
[外链图片转存中…(img-u3UtbVsY-1714305785633)]
Java中高级面试高频考点整理
[外链图片转存中…(img-6biSWUHv-1714305785634)]
[外链图片转存中…(img-MyGLEWWG-1714305785634)]
最后分享Java进阶学习及面试必备的视频教学
[外链图片转存中…(img-EeC8PImc-1714305785635)]