首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Fork-join中的内存可见性

Fork-join中的内存可见性
EN

Stack Overflow用户
提问于 2011-01-26 08:52:44
回答 2查看 1.4K关注 0票数 6

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

该算法同时对同一数组的两个不同部分进行排序。为什么不需要AtomicIntegerArray或其他机制来维护可见性?如何保证一个线程可以看到另一个线程完成的写操作,或者这是一个微妙的bug?接下来,Scala的ForkJoinScheduler是否也提供了这样的保证呢?

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-01-26 09:34:28

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

如果你看一下代码,你会发现同步点发生在哪里。这只是一个调用invokeAll的方法

代码语言:javascript
复制
public static void invokeAll(ForkJoinTask<?> t1, ForkJoinTask<?> t2) {
    t2.fork();
    t1.invoke();
    t2.join();
}

在这里,t2派生到另一个进程,t1执行它的任务,调用线程将等待t2.join()。在传递t2时。然后,对t1和t2的所有写入都将可见。

编辑:这个编辑只是为了更多地解释我所说的同步点。

假设你有两个变量

代码语言:javascript
复制
int x;
volatile int y;

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

代码语言:javascript
复制
public void doWork(){
   x = 10;
   y = 5;
}

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

使用Fork Join池,ForkJoinTask的联接将创建一个同步点。现在,如果t2.fork()和t1.voke()结合在一起,t2将确保可以看到之前发生的所有写操作。由于之前的所有写入都在相同的结构中,因此它将是安全的。

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

票数 8
EN

Stack Overflow用户

发布于 2011-01-26 09:12:16

只需猜测一下: merge包含对Thread的连接,而连接保证了可见性。

第二部分是肯定的;我不知道merge是如何实现的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4800503

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档