布莱恩·戈兹(Brian Goetz)写了一篇很好的文章 http://www.ibm.com/developererworks/java/library/j-jtp03048.html. 。在其中,他使用叉-Join机制列出了一种合并排序算法,在该算法中,他在该机制并行执行了阵列的两个侧面,然后合并结果。

这些算法同时在同一阵列的两个不同部分上分类。为什么不进行可见性的Atomicintegerarray或其他一些其他机制?有什么保证一个线程会看到另一个线程的写作,还是这是一个巧妙的错误?作为后续行动,Scala的Forkjoinscheduler是否也可以保证?

谢谢!

有帮助吗?

解决方案

(forkjoin的联接)本身需要一个同步点,这是最重要的信息。同步点将确保在上述点之后可见的所有写作。

如果您查看代码,则可以看到同步点发生的位置。这只是一种方法调用InvokeAll

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

在这里,T2分叉进入另一个过程,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创建一个同步点,在该点之前,所有以前的写入都将在书写后可见。

使用叉子联接池,forkjointask的联接将创建一个同步点。现在,如果t2.fork()和t1.invoke()T2的连接将确保将看到所有以前发生的写作。由于以前的所有写作都在相同的结构之内,因此可见性。

我很乐意进一步解释这是否不清楚。

其他提示

只是一个猜测:合并包括加入线程,加入保证了可见性。

第二部分是肯定的。我不知道如何实施合并。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top