文章目录
一、什么是CAS
CAS: Compare and Swap,翻译成比较并交换。是解决多线程并行情况下使用锁造成性能损耗的一种机制。执行函数CAS(V, E, N)
实现思想:CAS有3个操作数,内存值V,旧的预期值E,要修改的新值N。当且仅有预期值E和内存值V相同时,将内存值V修改为N。否则说明已经被其他线程更新,处理器不做任何操作。
二、CAS应用之原子类(Atomic类)
java.util.concurrent包中的Atomic 原子类
JUC并发包中Atomic原子类存放位置
1.原子更新基本类型类 cas
AtomicBoolean: 原子更新布尔类型。
AtomicInteger: 原子更新整型。
AtomicLong: 原子更新长整型。
2.原子更新数组
AtomicIntegerArray: 原子更新整型数组里的元素。
AtomicLongArray: 原子更新长整型数组里的元素。
AtomicReferenceArray: 原子更新引用类型数组里的元素。
3.原子更新引用类型
AtomicReference: 原子更新引用类型。
AtomicReferenceFieldUpdater: 原子更新引用类型的字段。
AtomicMarkableReferce: 原子更新带有标记位的引用类型,可以使用构造方法更新一个布尔类型的标记位和引用类型。
4.原子更新字段类
AtomicIntegerFieldUpdater: 原子更新整型的字段的更新器。
AtomicLongFieldUpdater: 原子更新长整型字段的更新器。
AtomicStampedFieldUpdater: 原子更新带有版本号的引用类型。
Unsafe类
- Unsafe类,全限定名是sun.misc.Unsafe,从名字中我们可以看出来这个类对普通程序员来说是“危险”的,一般应用开发者不会用到这个类。
- Unsafe底层是基于CAS实现的。
- Unsafe类是"final"的,不允许继承。且构造函数是private的。
- Atomic类中调用Unsafe方法保证多线程数据的正确性。
三、AtomicInteger类
AtomicInteger类保证多线程数据安全。
public class Thread01 implements Runnable {
private static Integer sum = 0;
private static AtomicInteger atomicInteger = new AtomicInteger(0);
@Override
public void run() {
cal();
}
private void cal() {
for (int i = 0; i < 10000; i++) {
sum++;
//原子类和lock锁底层都是cas实现的
atomicInteger.incrementAndGet();
}
}
public static void main(String[] args) throws InterruptedException {
Thread01 threadCount = new Thread01();
Thread thread1 = new Thread(threadCount);
Thread thread2 = new Thread(threadCount);
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(sum);//11979
System.out.println(atomicInteger.get());//20000
}
}
AtomicInteger底层基于CAS实现
public class AtomicInteger extends Number implements java.io.Serializable {
private static final long serialVersionUID = 6214790243416807050L;
// setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
private volatile int value;
//拿到当前的数值
public final int get() {
return value;
}
......
//数值加1
public final int incrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}
//数值减1
public final int decrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, -1) - 1;
}
......
}
四、CAS优缺点
优点:
- 避免用户态到内核态切换
缺点:
- 非常消耗cpu的资源
- 会出现ABA问题,可以通过添加版本号解决