سؤال

I read FutureTask class in jsr166, found that outcome object is non-volatile, the comments in code is "non-volatile, protected by state reads/writes" line 75, the state is volatile int. I have read Java Memory Model from Java Language Spec, but not found the accurate answer. Does anybody know the reason?

هل كانت مفيدة؟

المحلول

consider this program:

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;

If volatile read vr2 sees DONE, it means it happens after volatile write vw1. So we have happens-before relationships: w1 -> vw1 -> vr2 -> r2. Therefore write w1 is visible to read r2.

However succeed() isn't thread safe, since vr0 and vw1 are not atomic. If we use CAS

void succeed(Integer result)
    if( compareAndSet(state, PENDING, DONE) )      vr0+vw0
        this.result = result;                       w1

it fixes the atomicity issue. However, now w1 isn't necessarily visible to r2. The memory barrier effect of CAS is kind of like

void succeed(Integer result)
    if(state==PENDING)         vr0
        state=DONE;            vw0
        this.result = result;   w1

We have here vw0 -> vr2 -> r2, but w1 is not on the chain, there is no w1 -> r2

We must do the volatile write state=DONE after w1 to establish the happens-before chain.

void succeed(Integer result)
    if(state==PENDING)            vr0
        state=TMP;                vw0
        this.result = result;      w1
        state=DONE;               vw1

or in CAS

void succeed(Integer result)
    if( compareAndSet(state, PENDING, TMP) )       vr0+vw0
        this.result = result;                       w1
        state=DONE;                                vw1
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top