gpt4 book ai didi

java - 为什么 FutureTask 中的结果对象是非 volatile 的?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:50:27 25 4
gpt4 key购买 nike

我读了jsr166中的FutureTask类,发现outcome对象是non-volatile的,代码中的注释是“non-volatile, protected by state reads/writes”第75行,state是volatile int。我已经从 Java Language Spec 阅读了 Java 内存模型,但没有找到准确的答案。有人知道原因吗?

最佳答案

考虑这个程序:

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 之后。所以我们有 happens-before 关系: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 之后执行 volatile 写入 state=DONE 以建立 happens-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

关于java - 为什么 FutureTask 中的结果对象是非 volatile 的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14432400/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com