我有点理解 AtomicInteger 和其他 Atomic 变量允许并发访问。在什么情况下通常使用此类?
原文由 James P. 发布,翻译遵循 CC BY-SA 4.0 许可协议
我有点理解 AtomicInteger 和其他 Atomic 变量允许并发访问。在什么情况下通常使用此类?
原文由 James P. 发布,翻译遵循 CC BY-SA 4.0 许可协议
我能想到的最简单的例子就是使递增成为一个原子操作。
使用标准整数:
private volatile int counter;
public int getNextUniqueIndex() {
return counter++; // Not atomic, multiple threads could get the same result
}
使用原子整数:
private AtomicInteger counter;
public int getNextUniqueIndex() {
return counter.getAndIncrement();
}
后者是执行简单突变效果(特别是计数或唯一索引)的一种非常简单的方法,而无需求助于同步所有访问。
可以使用更复杂的无同步逻辑 compareAndSet()
作为一种乐观锁定 - 获取当前值,基于此计算结果,设置此结果 iff 值仍然是用于进行计算的输入,否则重新开始 - 但计数示例非常有用,我会经常使用 AtomicIntegers
进行计数和 VM-wide unique generators 如果有任何涉及多个线程的提示,因为它们非常简单与我一起工作我几乎认为使用普通 ints
是过早的优化。
虽然您几乎总是可以通过 ints
和适当的 synchronized
声明实现相同的同步保证,但 AtomicInteger
的美妙之处在于内置于实际线程安全中对象本身,而不是您需要担心碰巧访问 int
值的每个方法可能的交错和持有的监视器。调用 getAndIncrement()
时意外违反线程安全比返回 i++
并记住(或不)事先获取正确的监视器集要难得多。
原文由 Andrzej Doyle 发布,翻译遵循 CC BY-SA 2.5 许可协议
8 回答6.4k 阅读
1 回答4.2k 阅读✓ 已解决
3 回答2.3k 阅读✓ 已解决
2 回答3.2k 阅读
2 回答3.9k 阅读
3 回答1.7k 阅读✓ 已解决
1 回答2k 阅读✓ 已解决
AtomicInteger
有两个主要用途:作为原子计数器(
incrementAndGet()
等),可以同时被多个线程使用作为支持 比较和交换 指令 (
compareAndSet()
) 以实现非阻塞算法的原语。这是来自 Brian Göetz 的 Java Concurrency In Practice 的非阻塞随机数生成器示例:
如您所见,它的工作方式基本上与
incrementAndGet()
几乎相同,但执行任意计算 (calculateNext()
) 而不是递增(并在返回前处理结果)。