AtomicInteger能够保证对一个整型的操作是原子性。像i++这个操作不是原子操作,存在竞态条件,所以需要加锁,但是加锁的性能不高,如果仅仅为了对一个整数加1。我们来看下他的实现。
private volatile int value;
AtomicInteger本身持有一个整型变量,所有的操作都是基于这个变量的。变量由violate修饰,这个变量是保证可见性的,具体可见另一篇博客
来看一下对value加1的操作
public final int getAndIncrement() { for (;;) { int current = get(); int next = current + 1; if (compareAndSet(current, next)) return current; } }
代码嵌套在一个for循环里,关键是在compareAndSet方法里。这个方法会托管给unsafe的compareAndSwapInt方法,这个步骤是靠硬件支持的,是原子操作。这个方法的意思是,如果value等于current,那么将value置为next,返回true,否则返回false,继续下一轮循环。为什么会出现值不一致,原因就在竞态条件,当本线程将value值赋给current后,其它线程可能修改了value的值,这样就会出现current和value不一致的情况。可以看出来compareAndSet类似乐观锁,及时失败。总结来说就是,value的可见性由voilate保证,原子性操作由compareAndSet来保证。
其它的方法,操作也类似,都是依靠compareAndSet来保证
时间: 2024-12-19 18:51:32