compareAndSet(CAS, 自旋锁)理解
背景CAS?自旋是什么意思?CAS是怎么保证原子性操作的?CAS带来的ABA问题,及解决方案?过程CAS compareAndSet,compareAndExchange,compareAndSwap这个函数会先进行比较,如果相比较的两个值是相等的,那么就进行更新操作。CAS使用场景AtomicInteger atomicInteger = new AtomicInteger(1);atomicI
·
背景
- CAS?
- 自旋是什么意思?
- CAS是怎么保证原子性操作的?
- CAS带来的ABA问题,及解决方案?
过程
- CAS compareAndSet,compareAndExchange,compareAndSwap
这个函数会先进行比较,如果相比较的两个值是相等的,那么就进行更新操作。 - CAS使用场景
AtomicInteger atomicInteger = new AtomicInteger(1);
atomicInteger.compareAndSet(1, 2);
- 初始值是1
- compareAndSet(expect, update), 要想更新成功的话,那么这个expect的值一定是1,否则是不会被更新的。
AtomicInteger atomicInteger = new AtomicInteger(1);
atomicInteger.compareAndSet(2, 3);
- 上面的语句,就永远无法把值更新为3。
- 自旋操作
线程一直在执行逻辑,也就是一直让CPU进行计算操作。 - CAS保证原子性操作
是一个unsafe类下面的native方法。
最终保证原子性是通过,硬件层面的指令,comxchg完成的。如果是多核的情况下,就会上锁。LOCK_IF_MP(mutil Processors) - ABA问题及解决方案
- Thread1和Thread2都拿到值,都为A
- Thread2把A值更新为B
- 此时,Thread1还在处理自己的业务逻辑,然后Thread3拿到的值是B,然后又把值更新为A
- 此时,Thread1进行更新操作,发现更新成功了。出现了ABA问题,按理说,Thread1是不能更新值的。
- 更新的时候添加一个version版本号就可以了,解决这个问题。在理解上,可以理解为乐观锁。其实,加这个版本号,相当于又是一个CAS过程。
Student student = new Student();
student.setStatus(1);
AtomicReference<Student> studentAtomicReference = new AtomicReference<>(student);
if (studentAtomicReference.get().getStatus() == 1) {
Student updateStudent = new Student();
updateStudent.setStatus(2);
studentAtomicReference.compareAndSet(student, updateStudent);
}
小结
- 理解CAS的概念。
- 理解原子类底层实现都是CAS。
- 理解CAS是通过CPU指令来达到原子性的。
- 理解CAS存在的ABA问题,以及相应的解决方案。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献2条内容
所有评论(0)