Jack Shirazi によるJava Performance Tuningでは、次のように書いています。
これは、変数のアクセスと更新が自動的に同期されることを意味します (変数が long または double でない限り)。メソッドが変数へのアクセスまたは代入だけで構成されている場合、スレッド セーフのために同期化する必要はなく、パフォーマンスのためにそうしない理由もあります。スレッド セーフは、他の変数値とは関係なく、変数にアクセスしたり、変数に代入したりするステートメントのセットにさらに拡張されます。
上記の説明によると、操作 likeflag = true
は常にアトミックであり、 は必要ありませんsynchronize
。
ただし、次の状況をデータ競合と見なす別の記事があります。
class DataRaceExample {
static boolean flag = false;//w0
static void raiseFlag() {
flag = true;//w1
}
public static void main(String... args) {
ForkJoinPool.commonPool().execute(DataRaceExample::raiseFlag);
while (!flag);//r_i, where i ∈ [1, k), k may be infinite
System.out.print(flag);//r
}
}
そして著者は次のように述べています。
現在、フラグは揮発性ではないため、すべての実行にデータ競合があります
2 つの記事の矛盾について、私はかなり混乱しました。