谈谈对volatile,synchronize,cas的理解,可以考虑下使用场景?底层原理?以及happens before,lost wake up 这些相关规则及原理
更多问答 >>
-
2019-05-21 23:59
-
每日一问 思考一下如果捕获一个 Activity页面上所有的点击行为?
2019-05-23 00:14 -
每日一问 你有什么好的学习习惯 或者 不错的 app 推荐给大家?
2019-05-24 11:09 -
每日一问 View的onAttachedToWindow ,onDetachedFromWindow 调用时机,使用场景是什么?
2019-05-26 19:19 -
2019-05-29 12:23
-
讨论 | Flutter Kotlin 如果二选一学习,你会怎么选?
2019-05-16 09:04 -
2019-05-17 00:38
-
2019-05-13 08:30
-
2019-04-11 18:34
-
2019-04-09 23:44

volatile:
之前看过一个播放器的源码,里面的单例实例使用了volatile修饰,后来查了一下资料,了解到CPU在执行指令时,为了提高执行效率,会把内存中的数据copy一份到高速缓存中,所以程序在访问或修改变量的时候,操作的并不是内存中的数据,而是高速缓存中的数据。这样的话,在多核心CPU + 多线程上,可能会出现 [新写入的数据] 未能立即更新到 [内存] 中,这时候,如果有其他线程刚好又访问到这个变量,那么它读取到的数据,还是旧数据。使用volatile关键字修饰的变量,在程序修改它的数据之后,其他线程总是能拿到最新的值。在多线程的环境下,某个变量(比如说一个FLAG),会被多个线程频繁访问和修改,就可以使用volatile。synchronized:
这个关键字在代码中很常见,一个悲观锁 + 可重入锁cas:
相比与前面的synchronized,CAS机制是一种乐观锁,它不会阻塞其他线程,所以在效率上,会比synchronized高。在多线程共同修改同一变量的场景下,比如说,两个线程[A, B]同时把一个int类型的变量[m] 加上520 (m += 520),假设[A,B]拿到的初始值都是0,在运算之后,A和B都拿着520,想把它交给变量m,如果这时候,A比B快一步,先给了m,那么B接下来就会提交失败,为什么呢,因为它刚刚拿到m的初始值是0,但是现在看到m的值是520,很明显被别人修改了,在这种情况下,它会把现在的520取出来,把它再加上520,准备放回去,在放回去的时候,仍然会继续判断它刚刚拿到的m值的是不是最新的,如果不是最新的,还会继续前面的行为。典故:
5月19那晚上,两个男生在微信上约了同一个女生,女生都同意了。520那天早上,女生 先和男生A见面,岂料男生A会在这时候向她表白,并给她转账520块钱,她很惊喜,于是答应了。
当天下午,女生和男生B约会,这时候男生B居然也说喜欢她,向她表白了。。。。但是!她说,你慢了一步,我今天早上已经答应了另一个男生,做他女朋友了,你死心吧。但是没想到,男生B居然说: "没事啊,这年头多一个男朋友也没什么的。" ,女生只有害羞地点点头。 接着,男生B给女生转账了520。 女生开心地说: "那我现在有两个男朋友啦"。其实这位女生对CAS理解得非常深刻,因为如果按照一般的方式,她当天就只能收到520块,并且只有一个男朋友,但是当她把CAS机制应用到生活中,她就能收到1040块钱了,并且拥有2个男朋友。后来人们给这个故事起了个名字,叫做 "CAS爱情故事"happens before, lost wake up,这两个不会。。。没了解过谢谢你~
对 volatile,synchronize,cas的理解和我基本一致,但后面happens before, lost wake up 我也还没了解过,赶紧去了解一波 ...查看更多
对 volatile,synchronize,cas的理解和我基本一致,但后面happens before, lost wake up 我也还没了解过,赶紧去了解一波
虽然时间已经过去很久了,但我还是想纠正一下这位同学对于volatile在单例模式中应用的理解。 volatile在双重检查锁形式的单例中,不仅起到内存可见性作用,还起到了禁用指令重排的作用。 ...查看更多
虽然时间已经过去很久了,但我还是想纠正一下这位同学对于volatile在单例模式中应用的理解。 volatile在双重检查锁形式的单例中,不仅起到内存可见性作用,还起到了禁用指令重排的作用。
volatile小故事补充:
两个男生(A,B)同时喜欢上一个女生,但他们的示爱方式却截然不同,
男生A每个周末都会拿着一束鲜花到女生家门前,并等候着女生的答案,但这位女生却从来不看男生一眼,每次过了好几个小时之后,才在厅里大声说: "你回去吧,我开始打游戏了!"。然而,女生打的太极并没有使男生A放弃,反而更加坚定了他的决心。 男生B,因为跟那位女生是同桌,所以他比男生A有更多跟女生接触的机会,但是他并没有珍惜,每次放学就只会仗着女生打不过他,逼着女生帮他写作业,因为他觉得这样做,会有一种征服感。 某个周末,男生A一如既往地捧着鲜花来到女生家门前等候着回复,没想到这一幕刚好被女生的妈妈看到了,妈妈心想: "这孩子,挺有耐心的",于是跟她女儿讲: "女儿啊,你看门外的男生,多有心,每周风雨不改地来送花,我觉得他挺靠谱的,要不你尝试跟他交往一下?", 那位女生说: "知道啦妈,等我打完这局游戏我就去开门"。 这时候,男生A忽然接到他爸爸的电话: "今天是外婆的生日,快点回家,准备去外婆家了"。于是男生A就回家了,走回去的路上还撞到了一个看起来有急事的男的,原来这个男的就是男生B,他妈妈今天突然说要检查他的作业,所以他赶过去那位女生家,想拿回作业本。 半个小时后,女生打完游戏,化了个妆之后,站在门背后,说了一大堆肉麻的话,然后开门了。。。。门前的男生B感动得热泪盈眶,没想到之前那么欺负她,她不但不怪他,还说要跟他在一起。 开门后女生也很惊讶,没想到,强迫自己帮忙写了大半个学期作业的坏男生,竟然也是周末送花的贴心男生(她不知道,送花的是男生A),两人冰释前嫌,开启了一段新的生活。 这个故事告诉我们,信息同步在某种场景下的重要性,如果当时这个女生能及时地放下手机,给门外的男生开门,迎接她的,可能是一段甜蜜的生活,但是她并没有这么做,跟了男生B之后,不知道有什么程度的家暴,在等着她。我居然看完了~
我居然也看完了
我居然也看完了
对于
synchronized,可能部分人了解的还是关于 重量级锁的概念,有必要了解下 偏向锁、轻量级锁概念。没记错的话,在java中,并发原先是不建议使用synchronize的(低效),但是后续的版本(java 8之后?)对synchronize的优化使得效率已经很高了、
JDK 1.6开始就已经引入轻量级锁、偏向锁了。从1.6开始,其实就推荐使用synchronized,毕竟未来很有可能还会对VM优化,从而再次提高synchronized性能。1.8的Concurre ...查看更多
JDK 1.6开始就已经引入轻量级锁、偏向锁了。从1.6开始,其实就推荐使用synchronized,毕竟未来很有可能还会对VM优化,从而再次提高synchronized性能。1.8的ConcurrentHashMap实现已经从ReentrantLock缓存synchronized了。
路过打个卡 ~~
除了上面的,还有一个伪共享问题
关于并发是一个很大的专题系列,小菜鸟推荐两篇自己觉得不错的文章 :
关于volatile的 : https://www.cnblogs.com/dolphin0520/p/3920373.html
接着就要看看各种锁的知识了,自旋锁、乐观锁、悲观锁、偏向锁。。。等等,名词看起来很强,实际了解就知道了, 涉及到各种 Lock 需要了解下 AQS,关于 AQS 的 一个系列文章 The java.util.concurrent Synchronizer Framework 中文翻译版 : http://ifeve.com/aqs/ 也可以看看原文
并且涉及到了 CAS ,可以看看 ConcurrentHashMap 的源码,同时还要有一点红黑树和位运算的知识,
“并发编程网” 以及 “importNew” 是两个讲java 很不错的参考网站,也可以看看这里
https://www.geeksforgeeks.org/java/
那么,有了 java 的并发基础之后,可以接着了解 c++ 的并发,还是略有不同的
接着,可以继续看看 Linux kernel 的并发怎么处理的,需要有一点链表、队列的知识,了解即可
volatile:用于修饰变量,能够保证有序性和可见性,无法保证原子性
synchronize:用于同步代码块或者方法同步