【问题标题】:What´s the difference between AtomicReference<Integer> vs. AtomicInteger?AtomicReference<Integer> 与 AtomicInteger 有什么区别?
【发布时间】:2013-04-14 15:38:43
【问题描述】:

我不明白这两者之间的区别:

AtomicReference<Integer> atomicReference = new AtomicReference<>(1);

对比

AtomicInteger atomicInteger = new AtomicInteger(1);

一般来说有人可以说什么时候使用 AtomicReference 吗? 希望可以有人帮帮我。谢谢。

【问题讨论】:

    标签: java concurrency java.util.concurrent atomicreference


    【解决方案1】:

    一个非常重要的区别是compareAndSetweakCompareAndSet 方法对AtomicReference&lt;Integer&gt; 的语义与它们对AtomicInteger 的语义不同。这是因为使用AtomicReference&lt;Integer&gt;,这些方法使用== 进行比较,两个Integer 对象可以相等而不是==。对于AtomicInteger,比较的是整数值相等,而不是引用标识。

    正如其他人所指出的,AtomicInteger 具有AtomicReference&lt;Integer&gt; 不具备的附加功能。此外,AtomicInteger 扩展了 Number,因此它继承了所有 Number 方法(doubleValue() 等),并且可以在需要 Number 时使用。

    【讨论】:

    • 值得指出的是,在 -127 到 128 范围内的自动装箱 Integer 对象是 intern 并且它们的 == 将返回 true 而超出此范围的 Integer 则不会。不过,使用new Integer(3) 创建的整数显然不会具有相同的标识。这可能会导致各种令人惊讶的行为。
    • @JedWesley-Smith - 好点。根据 API,该范围之外的值可能也会被缓存。因此,更糟糕的是,“令人惊讶的行为”在不同的 Java 平台上可能会有所不同。
    • 是的,这是一个不应该依赖的无证黑客。
    【解决方案2】:

    如果您只使用 set(...)get() 并没有太大区别,但 AtomicInteger 有一些其他方法,例如仅适用于整数的 incrementAndGet()

    AtomicReference 包装了 volatile Object,而 AtomicInteger 包装了 volatile int,因此它可以执行特定于整数的方法,包括递增、递减和添加方法。 AtomicInteger 还扩展了Number,这意味着它支持doubleValue()longValue() 等方法。

    【讨论】:

      【解决方案3】:

      AtomicReference 是一个泛型类,可以引用任意类型。
      如果你想原子地使用你自己的类的实例,你需要AtomicReference&lt;V&gt;

      AtomicInteger 是一个包含整数的特殊版本。它更高效(没有不必要的装箱),并且有incrementAndGet() 等有用的方法。

      【讨论】:

      • 另外,两个Integer 对象可以相等而不相同。
      【解决方案4】:

      正如其他人指出的那样,AtomicReference&lt;Integer&gt; 使用 == 来比较对象。因此,compareAndSet(expect, update) 将仅在 expect 等于使用 == 存储在您的原子引用中的对象时更新您的初始引用。

      如果您将AtomicReference 用于数字类型,即IntegerLong,可能会导致一些棘手的错误。请注意,这些类的静态构造函数(例如,Integer.valueOf(int value))返回内部缓存的小值对象。换句话说,对Integer.valueOf(5) 的两次不同调用会返回Integer 的相同实例。这是安全的,因为类是不可变的。结果,如果您使用AtomicReference&lt;Integer&gt; 而您实际上应该使用AtomicInteger,它可能对这些小数字有效,因为 == 实际上可能比较相同的对象。只有当你在某个时候开始处理更高的值时,情况才会变得更糟。

      总结起来,使用AtomicInteger 对数值运算更安全:)

      【讨论】:

      • 查看对 Ted Hopp 回答的评论,Integer 对象的实习只发生在受限集合中,而不是全部发生。依靠实习来使 == 工作被认为是有害的,因为它没有记录并且可能会改变。
      • 嗯,这就是我所说的“小值”。我不想指定范围,因为它可能会发生变化。我的结论正是你所说的:你永远不应该依赖 == 来处理数字对象。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-25
      • 1970-01-01
      • 2011-03-26
      • 1970-01-01
      • 1970-01-01
      • 2015-01-29
      • 2012-09-23
      相关资源
      最近更新 更多