二、CAS介绍

synchronized保证了内存的可见性和原子性,但是是基于独占锁来实现的,也就是同一时间只有一个线程能执行,大大降低了并发性。CAS就是另一种更好的实现


CAS操作

CAS即Compare And Swap,它是JDK提供的非阻塞原子性操作,提供了一系列的compareAndSwap方法
如:

1
2
public final native boolean compareAndSwapInt(Object o, long offset,int expected,
int x);
  • o: 对象内存位置
  • offset: 对象中的变量偏移值
  • expected: 变量预期值
  • int: 新的值

    这个操作的含义是: 如果对象o中内存偏移量为offset的值为expected,则使用新的值x替换。

其他非阻塞方法:

  • public native long objectFieldOffset(Field f);//获取变量的内存偏移
  • public native int arrayBaseOffset(Class<?> arrayClass);//返回数组中第一个元素的地址
  • public native int arrayIndexScale(Class<?> arrayClass); 返回数组中的元素的字节大小

CAS原理

CAS操作都包含在了UnSafe类中,都是native方法,提供了硬件级别的原子性操作,如最终调用intel x86处理器源代码。

CAS虽然很高效的解决原子操作,但是CAS仍然存在三大问题。ABA问题,循环时间长开销大和只能保证一个共享变量的原子操作

Unsafe类

以上CAS的操作被包含在Unsafe中,除了以上这些,它还包含其他的一些重要的方法:

  • public native void park(boolean isAbsolute, long time);①
  • public native void unpark(Object thread);②
  • public final int getAndSetInt(Object o, long offset, int newValue)③

其中①和②是阻塞当前线程和唤醒当前线程,③是一个自旋操作,一直尝试拿到最新的值并修改直到成功

1
2
3
4
5
6
7
 public final long getAndAddLong(Object o, long offset, long delta) {
long v;
do {
v = getLongVolatile(o, offset);
} while (!compareAndSwapLong(o, offset, v, v + delta));
return v;
}