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)をロックしていることがわかります。同じロックを取得および解放しているflag
2 つの間に が含まれているため、値はキャッシュからフラッシュされ、他のオブジェクトが存在するメモリ内で更新されます。スレッドはそれを見ることができます。sysouts
flag
レースをシミュレートするのは難しいので、このコードがスレッドセーフになり、スレッド 2 に加えられた変更が表示されるという理論的な可能性はありますflag
か?
はいの場合、を使用して同じ効果をvolatile
達成できSystem.out.println();
ますか?