CAS乐观锁
- 乐观锁
- 总是假设最好的情况,认为并发安全问题一定不会发生,所以不需要加锁。
- 每次去拿数据的时候都认为别人不会修改,所以不会上锁。
- 但是在最终更新数据的时候,会判断一下在此期间别人有没有更新过这个数据,如CAS算法的实现。
- CAS算法主要分成3步:
- 获取共享数据的值,拷贝副本到工作内存,保存到值 current
- 对工作内存中的共享数据进行操作,获得更新后的值 next
- 执行CAS (compare and set)操作,先去主存获取当前共享变量的值value,与自己的旧值current比较
- 如果二者相同,表示这段时间没有其他线程修改共享变量值,则同步 值 next 到主存
- 如果二者不同,表示这段时间有其他线程修改了共享变量值,则放弃本轮修改,重新执行整个CAS。
- 因此CAS一般写成一个while循环,修改成功则退出循环,否则就重试
- 如 AtomicBoolean、AtomicInteger、AtomicLong 就是这个干的
- CAS存在ABA问题:
- 当前线程只能感知共享变量的值有没有改变,假设别人从A改成了B,又改成了A,则当前线程感知不到,即ABA问题
- 可以使用版本号机制解决ABA问题,如原子类AtomicStampedReference,加入了版本号,每当修改值,版本号就会+1
- 如 AtomicStampedReference 加入了版本号,每当修改值,版本号就会+1。这样根据版本号就知道有没有别的线程修改过,而且还能知道修改过几次
- 再如 AtomicMarkableReference,他的版本号是一个boolean类型,所以只能判断是否修改过值,不知道修改过几次。
AtomicMarkableReference只能缓解ABA问题,如果别人修改标记后,又改回来,则无法感知。
- 乐观锁适用于多读的应用类型,这样可以提高吞吐量
相关内容