私は並行性に関しては初心者であり、問題を発見するときに自信がありません。かなり確立されたコードベースを調べていて、データ競合の影響を受けやすいと思われる次のコード (簡潔にするために編集) を見つけました。
public class Example extends Thread {
boolean condition = false;
public void run () {
while (true) {
synchronized (this) {
try {
while( condition ) wait();
}
catch (InterruptedException e) { /*for brevity*/ }
}
// non-blocking computation
}
}
public void setTrue () { condition = true; }
public void setFalse () {
synchronized (this) {
condition = false;
this.notifyAll();
}
}
}
私が理解している限りcondition
、同期ブロックを使用してもコンパイラはメモリバリアを発行しないため、揮発性でなければなりません。それがコンパイラーの揮発性ストアcondition
である場合は、setTrue
StoreEnter.
上記がデータ競合の影響を受けやすいと信じるのは正しいですか? もしそうなら、どうすれば例を通してデータ競合を目撃できますか (単に JMM によって提供される保証を知るのではなく)。スレッドがループ内でランダムに呼び出す単純なテストでsetTrue
は、データ競合は明らかになりません。
また、確認する条件が 1 つあり、それを待機するスレッドは 1 つだけなので、ここでの notifyAll の使用はやり過ぎだと思います。
ありがとうございました。