原子类AtomicInteger
原子类AtomicInteger
- public AtomicInteger(): 初始化一个默认值为0的原子型Integer
- public AtomicInteger(): 初始化一个指定值的原子型Integer
- int get(): 获取值
- int getAndIncrement(): 以原子方式将当前值加1,注意,这里返回的是自增前的值
- int incrementAndGet(): 以原子方式将当前值加1,注意,这里返回的是自增后的值
- int addAndGet(int data): 以原子方式将输入的数值与实例中的值(AtomicInteger的value)相加,并返回结果
- int getAndSet(int value): 以原子方式设置为newValue的值,并返回旧值。
AtomicInteger原理
自旋锁+CAS算法。
自旋:
在修改共享数据的时候,把原来的旧值纪录下来了:
- 如果现在内存中的值跟原来的旧值一样,证明没有其他线程操作过内存值,则修改成功。
- 如果现在内存中的值跟原来的旧值不一样了,证明已经有其他线程操作过内存值,则修改失败,需要获取现在最新的值,再次进行操作,这个重新获取就是自旋。
CAS算法:
- 有3个操作数(内存值V,旧的预期值A,要修改的值B)
- 当
A==V
,此时修改成功,将V改为B A!=V
,此时修改失效,不做任何操作,并重新获取现在的最新值(这个重新获取的动作就是自旋)
CAS与synchronized的区别
相同点:在多线程情况下,都可以保证共享数据的安全性
不同点:
- synchronized总是从最坏的角度出发,认为每次获取数据的时候,别人都有可能修改。所以在每次操作共享数据前,都会上锁。
- cas是假设每次获取数据别人都不会修改,所以不会上锁,只不过修改共享数据的时候,会检查一下,别人有没有修改过这个数据,如果别人修改过,那么我再次获取现在最新值,如果没有修改过,那么现在直接修改共享数据的值。