是否有必要将 AtomicReference 声明为 volatile?

发布于 2024-11-29 08:44:02 字数 132 浏览 1 评论 0原文

对于所有其他原子对象也一样吗?解释 AtomicInteger 的问题更容易。由于超过 1 个线程正在访问对 myInt 的引用,因此一个线程是否有可能看到该对象的已注册缓存值(例如 null),除非它也被声明为 volatile?如果不是怎么会呢?

The same for all other atomic objects? It's easier to explain the question for an AtomicInteger. Since more then 1 thread are accessing the reference to myInt, isn't it possible that one thread sees the registered cached value, for example null, for this object, unless it is also declared volatile? If not how come?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

用心笑 2024-12-06 08:44:02

它不仅没有必要,而且实际上在语义上是错误的。 AtomicReference 在其内部保存“真实”引用,并使用其自己的同步结构管理对其的访问。 JVM 自己的同步结构(synchronized易失性 等)并未使用。 AtomicReference 对象本身不应被视为易失性的。如果有的话,请考虑将其设为最终

另请考虑这个问题 - 易失性可以被认为是如果您只需要获取和设置操作,则可以使用 AtomicReference 进行替代。

Not only is it not necessary, it's actually semantically wrong. AtomicReference holds the "real" reference within itself, and manages access to it using its own synchronization constructs. The JVM's own synchronization constructs (synchronized, volatile, etc) and not used. The AtomicReference object itself should not be treated as volatile. If anything, consider making it final.

Also consider this question - volatile can be considered to be an alternative to using AtomicReference, if all you need is get and set operations.

野味少女 2024-12-06 08:44:02

“原子”对象不是不可变的,因此只有正确发布它们才应该是线程安全的。例如,当您执行此类操作时,您将需要使用 volatile 关键字。

volatile AtomicInteger counter = // initialize counter

int harvest(){
    AtomicInteger old = counter;
    counter = new AtomicInteger();
    return old.get();
}

如果从上面的代码中删除易失性,您确实可能会丢失一些增量。根据规范,您还可能获得对未完全构造的 AtomicInteger 对象的引用,从而获得未定义的行为。

那么,你需要将你的原子对象声明为易失性的吗?答案是视情况而定。它们只有在正确发布的情况下才是线程安全的,就像任何其他线程安全对象一样(不可变对象除外,这是一种特殊情况)。在大多数情况下,您应该将它们定为最终的。

The "atomic" objects are not immutable, so they should be thread safe only if they are published properly. For example, when you do something like this, you will need to use the volatile keyword.

volatile AtomicInteger counter = // initialize counter

int harvest(){
    AtomicInteger old = counter;
    counter = new AtomicInteger();
    return old.get();
}

If you remove the volatile from the above code, you could indeed lose some increments. According to the spec, you might also get a reference to an AtomicInteger object that is not fully constructed, and thus get undefined behavior.

So, do you need to declare your atomic object as volatile? The answer is it depends. They are only thread safe as long as they are published properly, as any other thread safe objects are (except immutable objects, which are special case). In most cases, you should make them final.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文