原子变量是不是保证 - “发生在关系之前”?
Posted
技术标签:
【中文标题】原子变量是不是保证 - “发生在关系之前”?【英文标题】:Do Atomic variables guarantee a - "happens before relationship"?原子变量是否保证 - “发生在关系之前”? 【发布时间】:2017-05-26 00:01:41 【问题描述】:我有一个要求,我需要在完成后发布“n”个线程的结果。为了检查所有线程是否已完成,我使用了 AtomicInteger (incrementAndGet()) 并将其值与最终变量进行比较。在进行检查之前,我将各个线程的结果写入共享对象(写入并发哈希图中,因为非同步数据结构似乎就足够了)。所以,我的问题是,在我的计数器通过“if”条件之前,所有线程是否都会完成对共享对象的写入(并且主线程是否能够看到一致的内存)?
这里是示例代码:
公共无效运行()
//Values is a concurrent hashMap.
values.put(Thread.currentThread().getName(), Thread.currentThread().getName());
if(counter.incrementAndGet() == 5)
//Do something
【问题讨论】:
你为什么不使用CountDownLatch
?
不想要任何等待线程。会将计数器对象作为监视器传递给所有正在执行的线程。
使用一时不必阻塞线程:getCount()
返回当前计数。仅await ()
块。
【参考方案1】:
查看package summary 获取java.util.concurrent.atomic
:
原子访问和更新的记忆效应一般遵循 volatile 的规则,如The Java Language Specification (17.4 Memory Model) 所述:
get
具有读取volatile
变量的记忆效应。set
具有写入(分配)volatile
变量的记忆效应。 [..]compareAndSet
和所有其他读取和更新操作(例如 getAndIncrement)具有读取和写入 volatile 变量的记忆效应。
incrementAndGet()
包含 set 和 get 操作,这意味着您确实有一个完整的 happens-before 边缘。
【讨论】:
以上是关于原子变量是不是保证 - “发生在关系之前”?的主要内容,如果未能解决你的问题,请参考以下文章
JUC并发编程 共享模型之内存 -- Java 内存模型 & 原子性 & 可见性(可见性问题及解决 & 可见性 VS 原子性 & volatile(易变关键字))(代码