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を使用する場合vr0vw1
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 に答える