final void push(ForkJoinTask<?> task) {
ForkJoinTask<?>[] a; ForkJoinPool p;
int b = base, s = top, n;
if ((a = array) != null) { // ignore if queue removed
int m = a.length - 1; // fenced write for task visibility
U.putOrderedObject(a, ((m & s) << ASHIFT) + ABASE, task);
U.putOrderedInt(this, QTOP, s + 1);
if ((n = s - b) <= 1) {
if ((p = pool) != null)
p.signalWork(p.workQueues, this);
}
else if (n >= m)
growArray();
}
}
U.putOrderedObject和U.putOrderedInt设置数组和WorkQueue的顶部。那么为什么不使用array [i] = task和top = s + 1.我正在阅读ForkJoinPool的源代码并解决这个问题。
来自oracle jdk 1.8(1.8.0_131)的源代码。
答案 0 :(得分:0)
Unsafe在VarHandle之前处理了栅栏问题。有关详细信息,请参阅Rob Austin's blog。 F / J作者完成了书中的每一招,以加快速度。 VarHandle之前的代码最难理解,现在稍微不那么容易了。
他使用自己的原始数组,而不是使用标准Java数组(如ConcurrentLinkedQueue及其额外的开销)。