【问题标题】:Visibility guarantees of atomic variables原子变量的可见性保证
【发布时间】:2021-07-15 18:03:59
【问题描述】:

阅读了很多关于易失性、原子性和可见性的内容后,仍然存在一个问题。在跨线程工作之后,当“b”被更新/读取时,“a”始终可见:

int a;
volatile int b;
a = 1; b = 1;
...
// different thread
if (b == 1) // do something with a, which is 1 now

对于作为单独对象的原子变量是否同样适用,以下是否有效?

int a;
AtomicInteger b = new AtomicInteger();
a = 1; b.set(1);
...
// different thread
if (b.get() == 1) // a guaranteed to be 1 here all the time ???

如果答案是否定的,那么它应该可以扩展 AtomicInteger 类并在其中包含“a”,因为 AtomicInteger 包装了一个 volatile。

【问题讨论】:

    标签: java visibility atomic volatile


    【解决方案1】:

    get() 相当于从 volatile 变量中读取,set() 相当于写入它。我们有一个 happens-before 关系,这里是 write -> read,因此,“a 保证在这里一直为 1”。这当然是在只有这两个线程执行的上下文中。

    【讨论】:

    • 感谢您的快速回答。让我紧张的是,文档将 AtomicInteger 称为变量,而它是一个单独的对象。但它的工作原理就像一个 volatile 变量。我猜这个语义应该会导致两个不同的缓存行在访问时可能会受到影响。将“a”包装到扩展的 Atomic 类中可能会将其减少到一个。
    【解决方案2】:

    如果只有文档没有明确指定:

    将变量的值设置为 newValue,其内存语义设置为就像变量被声明为 volatile

    如果这是唯一代码,您可以在 AtomicInteger 上工作,那么是的,a 保证是 1

    【讨论】:

      【解决方案3】:

      a 保证在这里一直是 1 ???

      不,其他 set 调用可能会在两者之间发生。

      但在volatile 的情况下也是如此。

      【讨论】:

        猜你喜欢
        • 2017-08-09
        • 2021-09-20
        • 1970-01-01
        • 2014-11-30
        • 1970-01-01
        • 1970-01-01
        • 2011-07-30
        • 2015-07-06
        • 1970-01-01
        相关资源
        最近更新 更多