tai*_*tco 8 java concurrency lock-free
我在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;
Run Code Online (Sandbox Code Playgroud)
如果性读vr2看DONE,这意味着性写后发生vw1.所以我们在关系之前就已经发生了: w1 -> vw1 -> vr2 -> r2.因此,写入w1是可见的r2.
但是succeed()不是线程安全的,因为vr0并且vw1不是原子的.如果我们使用CAS
void succeed(Integer result)
if( compareAndSet(state, PENDING, DONE) ) vr0+vw0
this.result = result; w1
Run Code Online (Sandbox Code Playgroud)
它解决了原子性问题.但是,现在w1不一定可见r2.CAS的记忆屏障效果有点像
void succeed(Integer result)
if(state==PENDING) vr0
state=DONE; vw0
this.result = result; w1
Run Code Online (Sandbox Code Playgroud)
我们在这里vw0 -> vr2 -> r2,但w1不在链条上,没有w1 -> r2
我们必须在state=DONE之后w1进行volatile写操作以建立before-before链.
void succeed(Integer result)
if(state==PENDING) vr0
state=TMP; vw0
this.result = result; w1
state=DONE; vw1
Run Code Online (Sandbox Code Playgroud)
或在CAS中
void succeed(Integer result)
if( compareAndSet(state, PENDING, TMP) ) vr0+vw0
this.result = result; w1
state=DONE; vw1
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
243 次 |
| 最近记录: |