2013-01-21 66 views

回答

5

考虑此程序:

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; 

如果挥发性读vr2看到DONE,这意味着性写vw1后发生。所以我们发生在关系之前:w1 -> vw1 -> vr2 -> r2。因此编写w1是可见的阅读r2

但是succeed()不是线程安全的,因为vr0vw1不是原子的。如果我们使用CAS

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

它修复了原子性问题。但是,现在w1不一定对r2可见。 CAS的内存屏障作用是那种喜欢

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

我们这里vw0 -> vr2 -> r2,但w1不上链,没有w1 -> r2

我们必须w1后做性写state=DONE建立在链之前发生。

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 
+0

非常有用的答案,更清楚地理解 – taigetco

相关问题