AtomicInteger可以替换同步吗?

时间:2010-11-17 23:32:02

标签: java

java.util.concurrent.atomic包的javadoc说明如下:

  

一个类的小工具包   支持无锁线程安全   对单个变量进行编程。

但我在任何AtomicInteger或AtomicBoolean类中都没有看到任何线程安全(同步或锁定)代码。

所以,这两个是相同的:

1.

int i;
synchronized(this){i++;}

2

AtomicInteger i = new AtomicInteger();
i.getAndIncrement();

更新:感谢您的回答。当我使用AtomicInteger时需要volatile吗?

5 个答案:

答案 0 :(得分:17)

他们会提供相同的原子性。你必须要注意的唯一事情就是你读的时候你必须用同步包装它

synchronized(this){ return i;}

编辑以回答您的修改:

AtomicInteger不需要易失性。要证明声明AtomicInteger最终。您需要AtomicInteger易失的唯一原因是AtomicInteger字段本身是否发生变化。类似于:

volatile AtomicInteger i = new AtomicInteger(0);

public void work(){
    i.incrementAndGet();
    //...do some other stuff
    i = new AtomicInteger(10);//because the field i is changing the field needs to be volatile 
}

你可以想象不应该这样,所以你不必担心这个领域是不稳定的。

答案 1 :(得分:9)

它们在功能上是等价的,但有一个细微的差别。 synchronized具有在this上获取和释放监视器的开销,而AtomicInteger通过本机方法调用实现,因此速度会明显加快。

答案 2 :(得分:3)

是的,它们功能相同。

如果您处于超高争用环境中,您可能会发现性能差异,但这种可能性很小。

答案 3 :(得分:2)

AtomicInteger使用下面的sun.misc.Unsafe来执行原子更新。

因此,在回答您的问题时,是的,AtomicInteger 是线程安全的

答案 4 :(得分:1)

  

使用AtomicInteger时需要使用volatile吗?

不一定。考虑你的例子:

  • 如果i是本地变量,或
  • 如果ifinal属性,或
  • 如果当前线程和初始化(或最后更新)i变量的线程在该事件之后已同步,

如果您将i声明为volatile,则没有任何区别。