gpt4 book ai didi

java - Fork-join 中的内存可见性

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:11:20 25 4
gpt4 key购买 nike

Brian Goetz 在 http://www.ibm.com/developerworks/java/library/j-jtp03048.html 上写了一篇关于 fork-join 的好文章.在其中,他列出了一种使用 fork-join 机制的归并排序算法,在该算法中,他并行地对数组的两侧执行排序,然后合并结果。

该算法同时对同一数组的两个不同部分进行排序。为什么不需要 AtomicIntegerArray 或其他一些机制来保持可见性?有什么保证一个线程会看到另一个线程完成的写入,或者这是一个微妙的错误?请问Scala的ForkJoinScheduler是否也有这个保证?

谢谢!

最佳答案

(ForkJoin 的)连接本身需要一个同步点,这是最重要的信息。同步点将确保在该点之后发生的所有写入都是可见的。

如果您查看代码,您可以看到同步点出现的位置。这只是一个调用 invokeAll 的方法

public static void invokeAll(ForkJoinTask<?> t1, ForkJoinTask<?> t2) {
t2.fork();
t1.invoke();
t2.join();
}

这里 t2 fork 到另一个进程,t1 执行它的任务,调用线程将等待 t2.join()。通过 t2 时。所有对 t1 和 t2 的写入都将可见。

编辑:此编辑只是为了对我所说的同步点的含义进行更多解释。

假设你有两个变量

int x;
volatile int y;

任何时候你写入 y 时,所有在你读取 y 之前发生的写入都是可用的。例如

public void doWork(){
x = 10;
y = 5;
}

如果另一个线程读取 y = 5,则该线程保证读取 x = 10。这是因为对 y 的写入创建了一个同步点,所有写入之前所述点将在写入后可见。

使用 Fork Join 池,ForkJoinTask 的加入将创建一个同步点。现在,如果 t2.fork() 和 t1.invoke() 加入 t2 将确保可以看到之前发生的所有写入。由于所有先前的写入都在同一结构中,因此可见性是安全的。

如果不是很清楚,我很乐意进一步解释。

关于java - Fork-join 中的内存可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4800503/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com