在线客服
扫描二维码
下载博学谷APP
扫描二维码
关注博学谷微信公众号
Java原子操作之CAS,CAS(Compare and Swap),即比较并替换,是用于实现多线程同步的原子指令。

1. 无锁的概念
在谈论无锁概念时,总会关联起乐观派与悲观派,对于乐观派而言,他们认为事情总会往好的方向发展,总是认为坏的情况发生的概率特别小,可以无所顾忌地做事,但对于悲观派而言,他们总会认为发展事态如果不及时控制,以后就无法挽回了,即使无法挽回的局面几乎不可能发生。
这两种派系映射到并发编程中就如同加锁与无锁的策略,即加锁是一种悲观策略,无锁是一种乐观策略,因为对于加锁的并发程序来说,它们总是认为每次访问共享资源时总会发生冲突,因此必须对每一次数据操作实施加锁策略。而无锁则总是假设对共享资源的访问没有冲突,线程可以不停执行,无需加锁,无需等待,一旦发现冲突,无锁策略则采用一种称为CAS的技术来保证线程执行的安全性,这项CAS技术就是无锁策略实现的关键,下面我们进一步了解CAS技术的奇妙之处。
2. 什么是CAS
CAS(Compare and Swap),即比较并替换,是用于实现多线程同步的原子指令。
执行函数:CAS(V,E,N)
其包含3个参数
• V表示要更新的变量
• E表示预期值
• N表示新值
假定有两个操作A和B,如果从执行A的线程来看,当另一个线程执行B时,要么将B全部执行完,要么完全不执行B,那么A和B对彼此来说是原子的。
实现原子操作可以使用锁,锁机制,满足基本的需求是没有问题的了,但是有的时候我们的需求并非这么简单,我们需要更有效,更加灵活的机制,synchronized关键字是基于阻塞的锁机制,也就是说当一个线程拥有锁的时候,访问同一资源的其它线程需要等待,直到该线程释放锁,
这里会有些问题:首先,如果被阻塞的线程优先级很高很重要怎么办?其次,如果获得锁的线程一直不释放锁怎么办?(这种情况是非常糟糕的)。还有一种情况,如果有大量的线程来竞争资源,那CPU将会花费大量的时间和资源来处理这些竞争,同时,还有可能出现一些例如死锁之类的情况,最后,其实锁机制是一种比较粗糙,粒度比较大的机制,相对于像计数器这样的需求有点儿过于笨重。
实现原子操作还可以使用当前的处理器基本都支持CAS的指令,只不过每个厂家所实现的算法并不一样,每一个CAS操作过程都包含三个运算符:一个内存地址V,一个期望的值A和一个新值B,操作的时候如果这个地址上存放的值等于这个期望的值A,则将地址上的值赋为新值B,否则不做任何操作。
CAS的基本思路就是,如果这个地址上的值和期望的值相等,则给其赋予新值,否则不做任何事儿,但是要返回原值是多少。循环CAS就是在一个循环里不断的做cas操作,直到成功为止。
CAS是怎么实现线程的安全呢?语言层面不做处理,我们将其交给硬件—CPU和内存,利用CPU的多处理能力,实现硬件层面的阻塞,再加上volatile变量的特性即可实现基于原子操作的线程安全。
3. CPU指令对CAS的支持
或许我们可能会有这样的疑问,假设存在多个线程执行CAS操作并且CAS的步骤很多,有没有可能在判断V和E相同后,正要赋值时,切换了线程,更改了值。造成了数据不一致呢?答案是否定的,因为CAS是一种系统原语,原语属于操作系统用语范畴,是由若干条指令组成的,用于完成某个功能的一个过程,并且原语的执行必须是连续的,在执行过程中不允许被中断,也就是说CAS是一条CPU的原子指令,不会造成所谓的数据不一致问题。
4. 悲观锁,乐观锁
说到CAS,不得不提到两个专业词语:悲观锁,乐观锁。我们先来看看什么是悲观锁,什么是乐观锁。
4.1 悲观锁
顾名思义,就是比较悲观的锁,总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。
4.2 乐观锁
反之,总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。我们今天讲的CAS就是乐观锁。
由于CAS操作属于乐观派,它总认为自己可以成功完成操作,当多个线程同时使用CAS操作一个变量时,只有一个会胜出,并成功更新,其余均会失败,但失败的线程并不会被挂起,仅是被告知失败,并且允许再次尝试,当然也允许失败的线程放弃操作。基于这样的原理,CAS操作即使没有锁,同样知道其他线程对共享资源操作影响,并执行相应的处理措施。同时从这点也可以看出,由于无锁操作中没有锁的存在,因此不可能出现死锁的情况,也就是说无锁操作天生免疫死锁。
5. CAS 的优点
非阻塞的轻量级乐观锁, 通过CPU指令实现, 在资源竞争不激烈的情况下性能高, 相比synchronize重量级悲观锁, synchronize有复杂的加锁, 解锁和唤醒线程操作.。
— 申请免费试学名额 —
在职想转行提升,担心学不会?根据个人情况规划学习路线,闯关式自适应学习模式保证学习效果
讲师一对一辅导,在线答疑解惑,指导就业!
相关推荐 更多
iHRM实战项目教程课程学什么?
要学习Activiti7工作流引擎、SAAS-HRM系统概述与搭建环境、SAAS-HRM-数据库设计与前端框架、SAAS-HRM系统用户权限设计概述、权限分配与jwt概述、权限分配与jwt概述、JWT的权限控制与Shiro入门、Shiro高级及SaaS-HRM的认证授权等内容。
8821
2019-11-08 10:24:19
MySQL数据库性能优化是什么?
MySQL数据库目前已被Oracle收购,并发展处多个版本。MySQL是一种开放源代码的关系型数据库管理系统RDBMS,使用最常用的数据库管理语言--结构化查询语言SQL进行数据库管理。
6820
2019-11-22 15:44:54
Spring与Web环境集成总结
今天咋们要学习的是SpringMVC框架中Spring与Web环境集成的内容,主要涉及的知识点有ApplicationContext应用上下文获取方式,Spring提供获取应用上下文的工具,导入Spring集成web的坐标,配置ContextLoaderListener监听器以及通过工具获得应用上下文对象。下面我们来看看具体的学习内容吧~
5799
2020-04-17 20:33:31
学习Java语言有哪些优势?
对于IT行业的学习和从业者来说,Java语言的学习是绕不开的话题。Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点。Java语言的学习需要花费很大的心力和时间,想要更加高效地掌握Java,建议找一个靠谱的培训机构系统学习。
6353
2020-05-29 11:43:02
想学Java大学应该报哪个专业?
想学Java大学应该报哪个专业?大部分人会选择计算机应用技术或计算机科学与技术专业,里面涉及Java相关的课程,还有一些计算机基础知识,毕业以后从事软件开发的工作是比较对口的。Java是一种软件开发技术,大学一般不会重点教,会开这么一门课程,一周1-2个课时,教学内容相当有限算入门级别,想深入学习建议再报个Java培训班学习。
7753
2021-01-28 14:38:03
