Java中的Atomic Integer和Normal immutable Integer类有什么区别?

时间:2016-08-09 09:30:18

标签: java multithreading concurrency atomic compare-and-swap

由于Integer类也是不可变类,我们知道不可变类是线程安全的,因此需要Atomic Integer。 我很迷惑 。 这是因为读取和写入不可变对象不必是原子的,而原子整数的读写是原子的。 这意味着原子类也是线程安全的。

4 个答案:

答案 0 :(得分:5)

当您需要确保只有一个线程可以更新int变量时,AtomicInteger用于多线程环境。优点是不需要外部同步,因为修改它的值的操作是以线程安全的方式执行的。

考虑以下代码:

private int count;

public int updateCounter() {
   return ++count;
}

如果多个线程调用updateCounter方法,那么它们中的一些可能会收到相同的值。因为++计数操作不是原子的,因为它不仅仅是一个操作,而是由三个操作组成:read count, add 1 to it's value and write it back to it。多个调用线程可以将变量视为未修改为其最新值。

以上代码应替换为:

private AtomicInteger count = new AtomicInteger(0);
public int updateCounter() {
    return count.incrementAndGet();
}

incrementAndGet方法保证以原子方式递增存储的值,并在不使用任何外部同步的情况下返回它的值。

如果你的价值永远不会改变,你就不必使用AtomicInteger,它应该使用int。

答案 1 :(得分:3)

虽然根据定义不可变对象是线程安全的,但是可变对象也可以是线程安全的。

这正是Atomic...类(AtomicIntegerAtomicBoolean等等)的目的。

各种...get......set...方法允许线程安全访问和对象的变异。

毫不奇怪,该类在java.util.concurrent包中声明。

您只需浏览java.util.concurrent.atomic包的API

  

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

答案 2 :(得分:2)

考虑一个变量

int myInt = 3;

AtomicIntegermyInt有关。

Integer3有关。

换句话说,你的变量是可变的并且可以改变它的值。虽然值3是整数文字,但是常量,不可变表达式。

整数是文字的对象表示,因此是不可变的,你基本上只能读它们。

AtomicIntegers是这些值的容器。您可以阅读和设置它们。与将值赋值给变量相同。但与更改int变量的值不同,AtomicInteger上的操作是原子的。

例如,这不是原子

if(myInt == 3) {
   myInt++; 
}

这是原子

AtomicInteger myInt = new AtomicInteger(3);

//atomic
myInt.compareAndSet(3, 4);

答案 3 :(得分:2)

AtomicInteger是线程安全的(实际上,java.util.concurrent.atomic包中的所有类都是线程安全的),而普通整数不是线程安全的。

你需要'同步'和& 'volatile'关键字,当你在多线程环境中使用'Integer'变量(使其线程安全)时,与原子整数一样,你不需要'synchronized'和& 'volatile'关键字作为原子整数来处理线程安全。

另外,我会推荐以下有用的教程: http://tutorials.jenkov.com/java-concurrency/compare-and-swap.html

有关'atomic'包的更多信息,请参阅下面的oracle doc: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/package-summary.html