原子变量是不是保证 - “发生在关系之前”?

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 边缘。

【讨论】:

以上是关于原子变量是不是保证 - “发生在关系之前”?的主要内容,如果未能解决你的问题,请参考以下文章

关于synchronized与volatile的小析

JUC并发编程 共享模型之内存 -- Java 内存模型 & 原子性 & 可见性(可见性问题及解决 & 可见性 VS 原子性 & volatile(易变关键字))(代码

J.U.C中的原子变量

并发编程__原子变量

volatile在i++情况下失效,volatile不是原子的

volatile为啥不能保证原子性