AtomicInteger和volatile [英] AtomicInteger and volatile

查看:301
本文介绍了AtomicInteger和volatile的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道 volatile 允许可见性, AtomicInteger 允许原子性。
所以如果我使用volatile AtomicInteger ,这是否意味着我不必再使用任何同步机制了?



例如。

  A类{

私有易失性AtomicInteger计数;

void someMethod(){
//做一些事情
if(count.get()< 10){
count.incrementAndGet();
}
}

这是线程安全吗?

解决方案

我认为 Atomic * 实际上给出了两者原子性和波动性。因此,当您调用(例如) AtomicInteger.get()时,您可以保证获得最新的值。这记录在 java.util.concurrent.atomic 包文档


记忆效应对于原子的访问和更新,通常遵循挥发性规则,如Java™语言规范第17.4节所述。




  • get has the have读取volatile变量的记忆效应。

  • set具有写入(赋值)volatile变量的记忆效应。

  • lazySet具有记忆效应写入(赋值)一个volatile变量,除了它允许对后续(但不是先前的)内存操作进行重新排序,这些内存操作本身不会对普通的非易失性写入施加重新排序约束。在其他用法上下文中,> - lazySet可能在归零时为了垃圾收集而应用,这是一个永远不会再次访问的引用。

  • weakCompareAndSet以原子方式读取并有条件地写入变量但是不创建任何发生前的排序,因此不提供与weakCompareAndSet的目标之外的任何变量的先前或后续读取和写入的保证。

  • compareAndSet和所有其他读取和 - -update操作(如getAndIncrement)具有读取和写入volatile变量的内存效果。


现在如果你有

  volatile AtomicInteger count; 

volatile 部分意味着每个线程都会使用最新的 AtomicInteger 引用,以及它是 AtomicInteger 的事实意味着你查看该对象的最新值。



需要这个并不常见(IME) - 因为通常你不会重新分配 count 引用不同的对象。相反,你有:

 私人最终AtomicInteger count = new AtomicInteger(); 

此时,它是最终变量意味着所有线程都将处理同一个对象 - 事实上它是一个 Atomic * 对象意味着它们将看到该对象中的最新值。 / p>

I know volatile allows for visibility, AtomicInteger allows for atomicity. So if I use a volatile AtomicInteger, does it mean I don't have to use any more synchronization mechanisms?

Eg.

class A {

    private volatile AtomicInteger count;

    void someMethod(){
        // do something
        if(count.get() < 10) {
            count.incrementAndGet();
        }
}

Is this threadsafe?

解决方案

I believe that Atomic* actually gives both atomicity and volatility. So when you call (say) AtomicInteger.get(), you're guaranteed to get the latest value. This is documented in the java.util.concurrent.atomic package documentation:

The memory effects for accesses and updates of atomics generally follow the rules for volatiles, as stated in section 17.4 of The Java™ Language Specification.

  • get has the memory effects of reading a volatile variable.
  • set has the memory effects of writing (assigning) a volatile variable.
  • lazySet has the memory effects of writing (assigning) a volatile variable except that it permits reorderings with subsequent (but not previous) memory actions that do not themselves impose reordering constraints with ordinary non-volatile writes. Among other usage contexts, > - lazySet may apply when nulling out, for the sake of garbage collection, a reference that is never accessed again.
  • weakCompareAndSet atomically reads and conditionally writes a variable but does not create any happens-before orderings, so provides no guarantees with respect to previous or subsequent reads and writes of any variables other than the target of the weakCompareAndSet.
  • compareAndSet and all other read-and-update operations such as getAndIncrement have the memory effects of both reading and writing volatile variables.

Now if you have

volatile AtomicInteger count;

the volatile part means that each thread will use the latest AtomicInteger reference, and the fact that it's an AtomicInteger means that you'll also see the latest value for that object.

It's not common (IME) to need this - because normally you wouldn't reassign count to refer to a different object. Instead, you'd have:

private final AtomicInteger count = new AtomicInteger();

At that point, the fact that it's a final variable means that all threads will be dealing with the same object - and the fact that it's an Atomic* object means they'll see the latest value within that object.

这篇关于AtomicInteger和volatile的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆