[英]why outcome object in FutureTask is non-volatile?
我在jsr166中讀取了FutureTask類,發現結果對象是非易失性的,代碼中的注釋是“非易失性的,受狀態讀/寫保護”第75行,狀態是volatile int。 我從Java Language Spec讀過Java Memory Model,但沒有找到准確的答案。 有人知道原因嗎?
考慮這個計划:
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
。 因此,寫入w1
對於讀取r2
是可見的。
但是vr0
succeed()
不是線程安全的,因為vr0
和vw1
不是原子的。 如果我們使用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
之后執行volatile write state=DONE
來建立before-before鏈。
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.