【Beautiful JUC Part.6】CAS 不可中断的典范
2022/2/10 6:13:43
本文主要是介绍【Beautiful JUC Part.6】CAS 不可中断的典范,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
【Beautiful JUC Part.6】CAS 不可中断的典范
一、什么是CAS
运用场合:并发场景,实现不能被打断的交换操作
主要思路:
- 我认为V的值应该是A,如果是的话那我就把它改成B,如果不是A(说明被别人修改过了),那我就不修改了,避免多人同时修改导致出错。
- CAS有三个操作数:
- 内存值V、预期值A、要修改的值B,当且仅当预期值A和内存值V相同时,才将内存值修改为B,否则什么都不做。最后返回现在的V值
- CPU的特殊指令
- 一个指令可以比较和赋值
二、CAS的等价代码、应用场景
1、演示案例
public class TwoThreadsCompetition implements Runnable{ private volatile int value; public synchronized int compareAndSwap(int expectedValue, int newValue) { int oldValue = value; if (oldValue == expectedValue) { value = newValue; } return oldValue; } @Override public void run() { compareAndSwap(0, 1); } public static void main(String[] args) throws InterruptedException { TwoThreadsCompetition r = new TwoThreadsCompetition(); r.value = 0; Thread t1 = new Thread(r, "线程1"); Thread t2 = new Thread(r, "线程2"); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(r.value); } }
模拟CAS操作
2、应用场景
- 乐观锁
- 并发容器
- concurrentHashMap
- 原子类
3、分析原子类的CAS
AtomicInteger类
AtomicInteger加载Unsafe工具,用来直接操作内存数据
用Unsafe来实现底层操作
用volatile修饰value字段,保证可见性
getAndAddInt方法分析
Unsafe类
总结
三、CAS的缺点
1、ABA问题
因为CAS只是做和原值相不相等的检查,并没有检查是否被修改。
假设有三个线程,原值是5,线程2把5改为7,线程3又把7改成5,等到第一个线程查看是否是5,发现真的是5,线程1以为没有任何线程对其进行修改,所以线程1就会把这个5改成所期待的值。但是实际上已经有人修改过了。
2、如何解决
可以添加版本号,比如说第一个版本的5,第二个版本的5
3、自旋时间过长
在原子类的getAndAddInt方法中可以看到,一直在cas部分自旋,如果一直等待锁,就会造成消耗资源的问题。
这篇关于【Beautiful JUC Part.6】CAS 不可中断的典范的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享