jsr166 の FutureTask クラスを読んだところ、結果オブジェクトが不揮発性であることがわかりました。コード内のコメントは「不揮発性であり、状態の読み取り/書き込みによって保護されています」75 行目で、状態は volatile int です。Java Language Specから Java Memory Model を読みましたが、正確な答えが見つかりませんでした。誰も理由を知っていますか?
1 に答える
7
このプログラムを検討してください:
volatile int state;
Integer result;
void succeed(Integer result)
if(state==PENDING) vr0
this.result = result; w1
state = DONE; vw1
Integer peekResult()
if(state==DONE) vr2
return result; r2
return null;
volatile read が表示される場合vr2
、DONE
それは volatile write の後に発生することを意味しますvw1
。したがって、事前発生関係があります w1 -> vw1 -> vr2 -> r2
。したがって、 writew1
は read から見えますr2
。
ただし、とはアトミックではないsucceed()
ため、スレッドセーフではありません。CASを使用する場合vr0
vw1
void succeed(Integer result)
if( compareAndSet(state, PENDING, DONE) ) vr0+vw0
this.result = result; w1
原子性の問題を修正します。ただし、 noww1
は必ずしも に表示されるわけではありませんr2
。CASのメモリバリア効果は
void succeed(Integer result)
if(state==PENDING) vr0
state=DONE; vw0
this.result = result; w1
ここvw0 -> vr2 -> r2
に がw1
ありますが、チェーンにはありません。w1 -> r2
事前発生チェーンを確立するには、揮発性書き込みstate=DONE
後を実行する必要があります。w1
void succeed(Integer result)
if(state==PENDING) vr0
state=TMP; vw0
this.result = result; w1
state=DONE; vw1
またはCASで
void succeed(Integer result)
if( compareAndSet(state, PENDING, TMP) ) vr0+vw0
this.result = result; w1
state=DONE; vw1
于 2013-01-21T05:30:06.753 に答える