CAS(比较与交换)--乐观锁
在线程开始时读取这些多线程共享的数据毛病将其保存到当前进程的副本中,我们称为旧值(old value),watch就是这样的一个功能。在执行更新前,比较当前线程副本保存的旧值和当前线程共享的值是否一致,如果不一致,那么该数据已经被其他线程操作过,此次更新失败。为了保持一致,线程就不去更新任何值,而将事物回滚;否则认为他没有被其他线程操作过,执行对应的业务逻辑,exec命令就是执行“类似”这样的一个功能。
ABA问题,ABA问题来自于CAS原理的一个设计缺陷。
时间顺序 | 线程1 | 线程2 | 说明 |
T1 | X=A | - | 线程1加入监控X |
T2 | 复杂运算开始 | 修改X=B | 线程2修改X,此时为B |
T3 | 处理简单业务 | - | |
T4 | 修改 | 线程2修改X,此时变回A | |
T5 | 结束线程2 | 线程2结束 | |
T6 | 检测X=A,验证通过,提交事务 | - | CAS原理检测通过,因为和旧值保持一致 |
所以,只是单独的旧值,还不够,还要加入其他的方法。比如hibernate对缓存的持久对象PO加入字段version值,每操作一次PO,version= version+1,这样采用CAS原理检测version,就能避免ABA问题。
来源:《JavaEE 互联网轻量级框架整合开发》