Java中CAS原理分析(volatile和synchronized浅析)
CAS是什么?
CAS英文解释是比较和交换,是cpu底层的源语,是解决共享变量原子性实现方案,它定义了三个变量,内存地址值对应V,期待值E和要修改的值U,如下图所示,这些变量都是在高速缓存中的,如果两个线程A,B分别通过cas方式同时修改共享变量,假设当A线程先获取时间片,如果发现V的值和E相等就将主内存值更新为U,如果不相等说明线程B在线程A更新之前已经成功更新过,线程A会失败重试,此时根据缓存一致性协议,线程A的本地副本会失效,需要从主内存再同步最新的变量到本地内存副本,在Java中通过调用UnSafe的compareAndSet类似方式调用,底层是c,反编译后操作系统指令是cmpxchg指令。
保证i++原子性
你一定会有一个疑问,被volatile修饰的变量i,i++为什么会有线程安全问题呢,也就是原子性的问题,我们还是举一个经典的i++案例一步步分析吧!我们知道在多线程情况下volatile保证了共享变量的可见性,顺序行,但唯独不能保证原子性,原因是i++是一个复合操作,大致可以分成3步,1.先从主内存拿到最新的i值,2.将i加1这个操作保存到操作数栈,3.从栈中取出i加1的值写回到主内存。OK,当线程AB同时执行i++操作时,比如线程A先获取时间片,执行完第2步,这是线程A还未执行完,时间片分配给线程B,B顺利执行完所有操作后并同步了主内存,假设我们i的初始值是1,那么此时主内存值是2,因为线程B执行完毕,cpu时间片又回到线程A手上,做第3步操作,此时同步到主内存的值还是2,看,线程A,B各做了一次加1的操作,但最终结果可能是2,cas的作用就来了,他能保证i++操作的原子性,为什么能保证原子性呢?cas可以把上面三个操作合并成一个操作,是原子的。
有什么好处?
大家都知道解决多线程安全需要用到锁的,可以用synchronized来解决,但是synchronized也有它的劣势,最主要是它是阻塞的,阻塞会有什么问题?性能啊,这是计算机人不能忍的,频繁内核外核切换,会严重浪费系统资源,所以就提了cas这个乐观锁概念,它是非阻塞的,操作系统不用在内核态与用户态来回切换,相当于用while循环方式获取锁,在性能上有一定提升。即使这样,也会有一定问题,下面我们来看看。
有什么问题?
1.ABA问题。
这个案例比较简单,线程A把共享变量i,从1变成2,再变成1,线程B想把i变成2,本来应该是不会成功,因为即时变量i现在是1,但是它的状态变化了,他的解决方案是版本号。相当于修改成功一次版本号增加1,就可以解决了,曾经被面试官问到一个问题,cas是线程安全的吗?答案不是线程安全的。
2.自旋时间过长。
如果一个线程拿到锁后,一直不释放,其他线程就只能一直循环等待。
3.只能保证一个共享变量的原子性。
像Automic包下面的基本上都只能保证一个变量的原子性。
JUC包下面使用!
可能有些童鞋看JDK源码会比较纠结一个点,发现volatile关键字一般都会和cas连用,如果不要volatile会怎么样呢?cas本身只作用于方法,cas对共享变量没有约束,如果不对共享变量做volatile修饰,是不可见的,不能够保证共享变量的实效性,需要等待共享变量主动同步到主内存,这是需要花时间的,效率更低下,所有在JUC并发包里一直可以看到这样的volatile关键字一般都会和cas组合。
总结
这篇文章,我们先引出了cas概念,并且说明了它的优缺点,做了案例介绍,简单的和synchronized关键字做了比较,最后,深入的说明了volatile关键字和cas连用的效率,这是我在深入思考后得到的结论,分享给大家,文章有一定阅读门槛,如果有想搞清楚童鞋,可以1v1私聊讨论交流。希望大家喜欢。点赞哦!
我是叫练,边叫边练,欢迎点赞和评论。
- 清除所有标记
- 清除选中的标记
- 错误类型
- 无错字 - 写作(在线版)
Java中CAS原理分析(volatile和synchronized浅析)的更多相关文章
- Java中CAS原理详解
在JDK 5之前Java语言是靠synchronized关键字保证同步的,这会导致有锁 锁机制存在以下问题: (1)在多线程竞争下,加锁.释放锁会导致比较多的上下文切换和调度延时,引起性能问题. (2 ...
- Java 中 ConcurrentHashMap 原理分析
一.Java并发基础 当一个对象或变量可以被多个线程共享的时候,就有可能使得程序的逻辑出现问题. 在一个对象中有一个变量i=0,有两个线程A,B都想对i加1,这个时候便有问题显现出来,关键就是对i加1 ...
- CAS原理分析
在JDK 5之前Java语言是靠synchronized关键字保证同步的,这会导致有锁(后面的章节还会谈到锁). 锁机制存在以下问题: (1)在多线程竞争下,加锁.释放锁会导致比较多的上下文切换和调度 ...
- Java中CAS详解
在JDK 5之前Java语言是靠synchronized关键字保证同步的,这会导致有锁 锁机制存在以下问题: (1)在多线程竞争下,加锁.释放锁会导致比较多的上下文切换和调度延时,引起性能问题. (2 ...
- 【漫画】CAS原理分析!无锁原子类也能解决并发问题!
本文来源于微信公众号[胖滚猪学编程].转载请注明出处 在漫画并发编程系统博文中,我们讲了N篇关于锁的知识,确实,锁是解决并发问题的万能钥匙,可是并发问题只有锁能解决吗?今天要出场一个大BOSS:CAS ...
- Java Reference核心原理分析
本文转载自Java Reference核心原理分析 导语 带着问题,看源码针对性会更强一点.印象会更深刻.并且效果也会更好.所以我先卖个关子,提两个问题(没准下次跳槽时就被问到). 我们可以用Byte ...
- Java并发编程知识点总结Volatile、Synchronized、Lock实现原理
Volatile关键字及其实现原理 在多线程并发编程中,Volatile可以理解为轻量级的Synchronized,用volatile关键字声明的变量,叫做共享变量,其保证了变量的“可见性”以及“有序 ...
- Java并发/多线程-CAS原理分析
目录 什么是CAS 并发安全问题 举一个典型的例子i++ 如何解决? 底层原理 CAS需要注意的问题 使用限制 ABA 问题 概念 解决方案 高竞争下的开销问题 什么是CAS CAS 即 compar ...
- Java中CAS 基本实现原理 和 AQS 原理
一.前言了解CAS,首先要清楚JUC,那么什么是JUC呢?JUC就是java.util.concurrent包的简称.它有核心就是CAS与AQS.CAS是java.util.concurrent.at ...
随机推荐
- Python_用PyQt5 建 notepad 界面
用PyQt5建notepad界面 1 # -*-coding:utf-8 -*- 2 """ 3 简介:用PyQt5做一个对话框,有菜单(2个.有独立图标.快捷键).提示 ...
- mysql之事物
1.事物,在事物中的sql语句,要么全部执行成功,要么全部执行失败,不会出现一条sql执行成功了,一条sql执行失败的问题. 2.开启事物:就是关闭mysql自己的自动提交事物的方式 3.commit ...
- 如何输入x的平方
随着电脑的普及,现在都流行在电脑上做教学课件,撰写文章,尤其是理科文献,涉及的数学符号有很多,它包括了我们常见的四则运算符号和平方.立方等,也包括了高等数学中用到的积分.极限符号等,打这些公式就需要用 ...
- 如何循序渐进、有效地学习JavaScript?
转载链接:https://www.zhihu.com/question/19713563/answer/23068003 分享一篇 超毛 的一篇文章<如何学习javascript>(原文链 ...
- Spring 对Apache Kafka的支持与集成
1. 引言 Apache Kafka 是一个分布式的.容错的流处理系统.在本文中,我们将介绍Spring对Apache Kafka的支持,以及原生Kafka Java客户端Api 所提供的抽象级别. ...
- linux(centos7.x)安装jdk
一.下载与安装 下载地址:链接:https://pan.baidu.com/s/1g7MF1xqlOxWnLGf2shl3NA 提取码:epae 下载完成后将安装包上传到linxu环境中,并将其 ...
- Java基础教程——结构化编程
结构化编程 各结构的图示请参见: https://www.cnblogs.com/tigerlion/p/10703926.html 选择结构 |-if:如果 |-else:其他:此外:否则. pub ...
- Java中的单例模式最全解析
单例模式是 Java 中最简单的设计模式之一,它是指一个类在运行期间始终只有一个实例,我们就把它称之为单例模式.它不但被应用在实际的工作中,而且还是面试中最常考的题目之一.通过单例模式我们可以知道此人 ...
- 区块链V1版本实现之三
部分程序代码(区块链的定义及遍历打印): 1 //创建区块链,使用Block数组模拟 2 type BlockChain struct { 3 Blocks []*Block 4 } 5 6 //实现 ...
- LeetCode 029 Divide Two Integers
题目要求:Divide Two Integers Divide two integers without using multiplication, division and mod operator ...