Atomic 与 CAS
Atomic 原子类:
原子类的一个操作时候不可中断的。即使在多线程时,一个操作一旦开始,就不会被其他线程干扰。
AtomicInteger常用方法
public final int get();//获取当前值
public final int getAndSet(int newValue);//获取当前值,并设置新的值
public final int getAndIncrement();//获取当前值,并自增
public final int getAndDecrement();//获取当前值,并自减
public final int getAndAdd(int delta);//获取当前值,并加上预期的值
boolean compareAndSet(int expect,int update);//如果当前值等于预期值,则以CAS的方式设置为新值
public final void lazySet(int newValue);//最终设置为newValue值,使用lazySet设置之后可能导致其他线程在之后一段时间内读到旧值
AtomicInteger类主要利用CAS(Compare and swap)
+volatile+native方法来保证操作原子性。其中CAS指拿预期的值和原本的一个值作比较,如果相同则更新成新的值。而volatile关键字保证该值的可见性,也就是说线程读取的都是内存的最新值。
CAS
即Compare and swap,是一种有名的无锁算法,在不用锁的情况下实现多线程间的同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也称非阻塞同步。
CAS算法涉及到三个操作数:
- 需要读写的内存值V
- 进行比较的值A
- 待写入的新值B
- ABA问题:一个变量V初次读取值为A,在赋值前检查到值仍然为A,这不代表这个值没有被修改过,因为在这段时间内它可能被修改为B,之后再修改回A,CAS操作因此就认为它没有被修改过。针对这种情况,Java 提供了 AtomicStampedReference 工具类,通过为引用建立类似版本号(stamp)的方式,来保证 CAS 的正确性。
- 循环时间开销