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 ...
随机推荐
- css子选择器 :frist-child :nth-child(n) :nth-of-type(n) ::select选择器
记录一下前一段时间使用.学习的几种选择器. 1. :frist-child 选择器n 比如<ul><li></li> <li></li> & ...
- [python应用]python简单图片抓取
前言 emmmm python简单图片抓取 1 import requests 2 import threading 3 import queue 4 from subprocess import P ...
- 面试阿里,字节跳动,华为必须知道的Java创建对象的5种方式
Java创建对象的5种方式 1.直接new,调用了构造器2.通过clone(),没有调用构造器3.通过反射,调用了构造器4.通过反序列化,没有调用构造器5.通过Unsafe类的allocateInst ...
- Camtasia中对录制视频进行编辑——音效
市场上有很多的视频处理软件,形形色色的软件往往会使人眼花缭乱,而对于那些短视频的制作者来说,拥有一款好的视频处理软件会让自己的视频收获更多的点赞.那么今天我便给大家推荐一款同时具有录屏和编辑视频功能的 ...
- 「CF645E」 Intellectual Inquiry
题目链接 CF645E 题意 有一个长为\(n\)的由小写字母组成的字符串,需要用小写字母再填\(m\)位,使最后的字符串中本质不同的子串数量尽量多,答案对\(10^9+7\)取模. 本题数据:\(n ...
- JUC并发工具包之CyclicBarrier & CountDownLatch的异同
1.介绍 本文我们将比较一下CyclicBarrier和CountDownLatch并了解两者的相似与不同. 2.两者是什么 当谈到并发,将这两者概念化的去解释两者是做什么的,这其实是一件很有挑战的事 ...
- 检查字符串结尾 判断一个字符串(str)是否以指定的字符串(target)结尾。
function confirmEnding(str, target) { var arr = str.replace(/\s+/g, ""); var bb = arr.subs ...
- iOS gif图显示问题
问题 有时候需要显示gif动态图,让界面更加的绚丽,但是iOS默认只支持png,gpg图片.那么如何才能显示gif图呢? 解决方式 添加框架 CoreGraphics.framework ImageI ...
- TCP/IP网络协议基础入门及实验
TCP/IP简介 提到网络协议栈结构,最著名的当属 OSI 七层模型,但是 TCP/IP 协议族的结构则稍有不同,它们之间的层次结构有如图对应关系: 可见 TCP/IP 被分为 4 层,每层承担的任务 ...
- zk下的kafka节点
zk从某种程度上说是kafka的单点失效组件. /brokers:里面保存了Kafk集群的所有信息,包括每台broker的注册信息,集群上所有topic的信息等. /controller:保存了Kaf ...