3

正しく同期されたプログラムはまだデータ競合を許可しますか?(パートI)の答えとして、それは良い例を示しています:プログラムのすべての実行は順次一貫しているように見えますが、それでもデータ競合があります。これは、 JLSで結論に従う別の方向が正しくない理由を示しています。

プログラムにデータ競合がない場合、プログラムのすべての実行は順次一貫しているように見えます。

次に、 JLSの別の結論を見てみましょう。

プログラムは、すべての逐次一貫性のある実行にデータ競合がない場合にのみ、正しく同期されます。

この結論によると、上記の例は正しく同期されていないので、正しいプログラムが正しく同期されていない可能性がありますか?

4

2 に答える 2

2

おそらく、最初に正しいプログラムとは何かを定義する必要があります(簡単ではありません)。JCiPは(別のコンテキストで)提案します:

プログラムが仕様に準拠していれば、プログラムは正しいです。

その定義を使用すると、提供されている例は正しいです。ただし、正しく同期されていません(にデータ競合がありますhash)。

==>その例で証明されているように、正しいプログラムが正しく同期されていない可能性があります。

于 2012-08-22T12:37:40.650 に答える
1

これはOPの質問に答えているようには見えませんが、コメントのために保管しています。


同期されたコレクションを使用して、いくつかの競合状態を取得できます。例えば

Vector<Integer> vector = ...
vector.add(1);

vector.set(0, 1 + vector.get(0));

各メソッドは同期されていますが、競合状態があります。これは、スレッドT1とT2に実行させることができるためです。

T1: int tmp1 = vector.get(0);
T2: int tmp2 = vector.get(0);
T1: vector.set(0, 1 + tmp1);
T2: vector.set(0, 1 + tmp2);

この場合、tmp1 == tmp2ですが、通常はそうではありません。

これを正しく同期するには、次の手順を実行して、常にロックを保持していることを確認します。

synchronized(vector) {
    vector.set(0, 1 + vector.get(0));
}
于 2012-08-22T12:37:32.180 に答える