System.out.println()コードをある程度スレッドセーフにすることを主張する多くの投稿を読んだことがあります。そのため、レースをシミュレートするにSystem.out.println()は、コードから削除する必要があります。
現在、 のwrite()メソッドはストリームに書き込む前にPrintStream同期するthisため、 が呼び出されるたびwrite()にロックが保持され、解放されます。
write()PrintStreamのメソッド
public void write(int b) {
try {
synchronized (this) { //acquires a lock
ensureOpen();
out.write(b);
if ((b == '\n') && autoFlush)
out.flush();
}
}
catch (InterruptedIOException x) {
Thread.currentThread().interrupt();
}
catch (IOException x) {
trouble = true;
}
}
しかし、それは人種の行動に影響を与えるでしょうか?
仮定する:
boolean flag = true;
Thread 1:
System.out.println();
flag = false;
System.out.println();
Thread 2:
System.out.println();
while(flag){
System.out.println();
}
ここで、両方のスレッドが同じオブジェクトthis(PrintStream)をロックしていることがわかります。同じロックを取得および解放しているflag2 つの間に が含まれているため、値はキャッシュからフラッシュされ、他のオブジェクトが存在するメモリ内で更新されます。スレッドはそれを見ることができます。sysoutsflag
レースをシミュレートするのは難しいので、このコードがスレッドセーフになり、スレッド 2 に加えられた変更が表示されるという理論的な可能性はありますflagか?
はいの場合、を使用して同じ効果をvolatile達成できSystem.out.println();ますか?