(ForkJoinの)結合には、最も重要な情報である同期ポイントが必要です。同期点は、発生したすべての書き込みが前記点の後に見えることを保証する。
コードを見ると、同期点の発生場所がわかります。これは、別のプロセスに一つだけここで
public static void invokeAll(ForkJoinTask<?> t1, ForkJoinTask<?> t2) {
t2.fork();
t1.invoke();
t2.join();
}
invokeAllメソッド呼び出しt2のフォークで、t1)は(そのタスクを実行し、呼び出し元のスレッドがt2.joinに待機します。 t2を通過するとき。 t1とt2へのすべての書き込みが表示されます。
編集:この編集は、私が同期点の意味を少し説明したものです。
は、次の2つの変数
int x;
volatile int y;
あなたがyにあなたはyが利用できるようになります読む前に起こったすべての書き込みを書く任意の時間を持っていると言うことができます。例えば
public void doWork(){
x = 10;
y = 5;
}
ために別のスレッドは、Yは、スレッドは、Yへの書き込みがすべての書き込みが前のポイントがされることを特徴とする同期ポイントを作成するため、これはX = 10を読み出すためにを保証されること5 =読み取る場合書き込み後に表示されます。
Fork Joinプールでは、ForkJoinTaskの結合によって同期ポイントが作成されます。今度は、t2.fork()とt1.invoke()がt2に参加すると、以前に発生したすべての書き込みが確実に表示されます。以前の書き込みはすべて同じ構造内にあるので、可視性は安全です。
それが明らかでない場合は、さらに説明していただきたいと思います。
アレイのさまざまなセクションで動作しています。マージするまでは競合はありません。 –
私は彼らが異なるセクションで動作していることに同意します。しかし、Javaのメモリモデルのセマンティクスは、すべてのスレッドがすべての書き込みを見ることが保証されているわけではない(変数がvolatileでない限り)。このブログによると:http://jeremymanson.blogspot.com/2009/06/volatile-arrays-in-java.html揮発性int []を使用するだけでは、他のスレッドが配列への書き込みを見ることを保証するには不十分です –