8

jsr166 の FutureTask クラスを読んだところ、結果オブジェクトが不揮発性であることがわかりました。コード内のコメントは「不揮発性であり、状態の読み取り/書き込みによって保護されています」75 行目で、状態は volatile int です。Java Language Specから Java Memory Model を読みましたが、正確な答えが見つかりませんでした。誰も理由を知っていますか?

4

1 に答える 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 が表示される場合vr2DONEそれは 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 に答える