synchronized保证了内存的可见性和原子性,但是是基于独占锁来实现的,也就是同一时间只有一个线程能执行,大大降低了并发性。CAS就是另一种更好的实现
CAS操作
CAS即Compare And Swap,它是JDK提供的非阻塞原子性操作,提供了一系列的compareAndSwap方法
如:
1 | public final native boolean compareAndSwapInt(Object o, long offset,int expected, |
- 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 | public final long getAndAddLong(Object o, long offset, long delta) { |