などの複合操作は複数のi++
操作を伴うため、スレッドセーフではないことを知っています。
しかし、スレッドセーフな操作で参照をチェックしていますか?
a != a //is this thread-safe
これをプログラムして複数のスレッドを使用しようとしましたが、失敗しませんでした。私のマシンではレースをシミュレートできなかったと思います。
編集:
public class TestThreadSafety {
private Object a = new Object();
public static void main(String[] args) {
final TestThreadSafety instance = new TestThreadSafety();
Thread testingReferenceThread = new Thread(new Runnable() {
@Override
public void run() {
long countOfIterations = 0L;
while(true){
boolean flag = instance.a != instance.a;
if(flag)
System.out.println(countOfIterations + ":" + flag);
countOfIterations++;
}
}
});
Thread updatingReferenceThread = new Thread(new Runnable() {
@Override
public void run() {
while(true){
instance.a = new Object();
}
}
});
testingReferenceThread.start();
updatingReferenceThread.start();
}
}
これは、スレッドセーフをテストするために使用しているプログラムです。
奇妙な行動
私のプログラムがいくつかの反復の間に開始すると、出力フラグ値を取得します。これは!=
、同じ参照で参照チェックが失敗したことを意味します。しかし、いくつかの反復の後、出力は定数値false
になり、プログラムを長時間実行しても単一のtrue
出力は生成されません。
出力が示唆するように、n 回 (固定されていません) 反復した後、出力は一定値のように見え、変化しません。
出力:
いくつかの反復の場合:
1494:true
1495:true
1496:true
19970:true
19972:true
19974:true
//after this there is not a single instance when the condition becomes true