假设以下两个计数器实现:
class Counter {
private final AtomicInteger atomic = new AtomicInteger(0);
private int i = 0;
public void incrementAtomic() {
atomic.incrementAndGet();
}
public synchronized void increment() {
i++;
}
}
乍一看,原子应该更快、更具可扩展性。我相信他们确实如此。但它们比synchronized
一直阻塞?或者在某些情况下会违反此规则(例如 SMP/单 CPU 机器、不同的 CPU ISA、操作系统等)?
incrementAndGet
很可能被实现为 CAS 循环。在高度满足的情况下,可能会导致n-1 个线程失败导致 O(n)问题,对于n线程。
(对于@Geek:
通常getAndIncrement
可以这样实现:
int old;
do {
old = value;
} while (!compareAndSet(value, old, old+1));
return old;
想象一下你有一个n线程在同一个原子上执行此代码,并且它们恰好彼此同步。第一次迭代确实kn工作。只有一个 CAS 会成功。另一个n-1 个线程将重复该练习,直到只剩下一个。所以总的工作量是 O(n^2)(最坏情况)而不是 O(n). )
话虽如此,获取锁最多需要做类似的事情,而当竞争激烈时,锁并不能发挥最佳作用。在使用 CAS 循环之前,您不太可能看到锁的太多优势,因为 CAS 循环在 get 和 CompareAndSwap 之前需要大量计算。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)