FutureTask 里使用普通语义而不是 CAS 写的原因是?

2020-08-16 23:57:14 +08:00
 amiwrong123

在 FutureTask 里面,普通写和 CAS 写是 混合使用的。比如

    public boolean cancel(boolean mayInterruptIfRunning) {
        if (!(state == NEW &&
              UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
                  mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
            return false;
        try {    // in case call to interrupt throws exception
            if (mayInterruptIfRunning) {
                try {
                    Thread t = runner;
                    if (t != null)
                        t.interrupt();
                } finally { // final state
                    UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);  //这里是普通写语义
                }
            }
        } finally {
            finishCompletion();
        }
        return true;
    }

我这么解释对吗:

1636 次点击
所在节点    Java
4 条回复
BBCCBB
2020-08-17 08:31:43 +08:00
手里的 jdk11 实现已经不是这个 putOrderedInt 了.
不过我感觉套路都差不多, 就是要么是在加锁里面执行的, 要么是有 volatile 字段更新, 捎带就把他的缓存给清了.
BBCCBB
2020-08-17 08:32:14 +08:00
amiwrong123
2020-08-17 10:43:06 +08:00
@BBCCBB
volatile 变量的修改可以立刻让所有的线程可见,这个确实很好理解,对于同一个字段来说。

但其实,对 A 字段的 CAS 写操作,可以让其他所有字段的普通写操作,也马上可见。我这么理解对不
BBCCBB
2020-08-17 13:16:58 +08:00
@amiwrong123 就我了解来说, 你的理解是对的, 这也是一个捎带同步的技巧..

你可以去看 happens before 规则里对 volatile 变量部分的描述.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/698787

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX