【问题标题】:Does volatile keyword lost its relevance due to AtomicXXX variables in multi-threaded applications?volatile 关键字是否由于多线程应用程序中的 AtomicXXX 变量而失去相关性?
【发布时间】:2016-05-17 16:39:20
【问题描述】:

来自文档page

包java.util.concurrent.atomic说明:

一个小的类工具包,支持对单个变量进行无锁线程安全编程。本质上,这个包中的类将 volatile 值、字段和数组元素的概念扩展到还提供表单的原子条件更新操作的那些类

boolean compareAndSet(expectedValue, updateValue);

在原子包中提供了许多选项,例如

AtomicBoolean
AtomicInteger
AtomicLongArray

等等,我可以使用这些 AtomicXXX 并慢慢摆脱遗留代码中的 volatile 变量吗?

编辑:

  1. 保持volatile 用于不同线程中的单次写入和多次读取操作(我在阅读了许多文章后得出的结论)、多写入器、单读取器的情况(根据@erickson cmets)
  2. 使用AtomicXXX 在多个线程之间进行多次更新和多次读取以避免synchronization。为 volatile 变量提供原子性。

@ericksoncomments.volatile 改变了我的思维过程,支持多写和单读`,但可能因多写和多读而失败。我对这个概念感到困惑。

【问题讨论】:

标签: java multithreading volatile


【解决方案1】:

是的,AtomicXXX 实例提供与访问 volatile 字段相同的可见性保证。

但是,AtomicXXXvolatile 字段更多,因此,它们的使用成本更高。具体来说,它们提供的操作更像是优化的synchronized 块,而不是volatile 读取或写入。您递增--获取,或比较--交换-多个操作,原子地。易失性变量不提供任何原子性。

因此,从volatile 切换到AtomicXXX 不一定是一个好举措。考虑到数据的使用方式是否有意义,也许对原型进行一些分析,看看它会对性能产生什么影响。

【讨论】:

  • @Ravindrababu 任何被多线程读写的字段都需要像volatile这样的内存屏障来确保可见性;但是volatile 仅在可以独立于所有其他字段修改该字段时才足够。它不仅限于单作者、多读者的情况。它也可以用于多作者、单读者的情况。
  • 除非有锁保护,否则多写不会导致不一致吗?抱歉,如果我没有正确理解您的观点。
  • 如果atomicInteger.get()atomicInteger.set(n)m=myVolatilemyVolatile=n 更昂贵,那不是因为addAndGetcompareAndSet 方法存在。可能是因为get()set() 是方法调用。
  • @Ravindrababu 锁获取和释放与 volatile 读写或 AtomicXXX 读写具有相同的内存语义。
  • @Ravindrababu 如果您的程序仅使用AtomicXXX.get()AtomicXXX.set() 是正确的,那么使用volatile 将是正确的。如果您需要在一些读写组合(如x++)中使用synchronized 来使您的程序正确,那么java.util.concurrent.atomic 包可能会提供更有效的替代方案。与volatile 相比,原子类型更接近于synchronized 关键字。
猜你喜欢
  • 2018-09-03
  • 2011-03-22
  • 1970-01-01
  • 2017-08-27
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
  • 2018-06-07
相关资源
最近更新 更多