延吉湖北乐清贵港襄阳宜春
投稿投诉
宜春榆林
滕州锦州
襄阳晋中
泰州云南
贵港许昌
娄底河南
乐清寿光
阜阳汉中
湖北漳州
海口陕西
延吉东营
河源海南

一次群聊引发的血案

11月7日 颜如初投稿
  就在不久前,读者群因为一个提问引发了激烈的讨论!
  代码如下图:
  从问题来看,大家讨论的问题的焦点在于map去put一个对象的时候,究竟会不会因为对象没有完全初始化完成而导致另外一个线程get的时候只是拿到了对象的引用,导致报错呢?
  从提供的代码的写法来看,是一个最基本的DCL稍微改变了的写法,在探讨map的问题之前,我想先从DCL(双重检查校验)说起。DCL的由来
  在最初的时候,我们常规的单例写法就像这样:
  很容易你就应该知道,这段代码不是线程安全的,所以有了加锁的单例方法实现。
  但是synchronized又会导致多线程下性能开销过大,虽然现在优化了,但是早期synchronized的性能是堪忧的,所以就诞生了双重检查锁定DCL的写法。先判断一次null,然后再加锁,这样第一次检查不是null的话就不需要加锁了,就可以避免synchronized的性能开销过大的问题。
  看样子问题是解决了,就很棒的样子,但是回到开头说的问题。DCL的问题
  从CPU的角度来看,instancenewInstance()可以分为分为几个步骤:分配对象内存空间执行构造方法,对象初始化instance指向分配的内存地址
  实际上,由于指令重排的问题,2、3的步骤可能会发生重排序,那么问题就发生了。
  instance先被指向内存地址,然后再执行初始化,如果此时另外一个线程来访问getInstance方法,就会拿到instance不是null,最后拿到的将是一个没有被完全初始化的对象!
  实际上,这个问题已经是大部分人都知道的DCL的一个问题了。
  因为根据Java内存模型语义来说,不管编译器和处理器怎么排序,单线程的执行结果都不能改变,只要数据没有依赖关系,就都可以重排序。
  那对上面的例子来说重排序改变了单线程下程序结果吗?并没有,因为无论线程A内是先初始化对象还是先把instance指向分配好的内存地址,对于单线程A的结果来说是没有任何改变的。
  也就是说,对于重排序的结果来说,只要保证线程B在访问对象的时候能拿到instance引用就可以,无论线程A内部初始化和执行内存地址两个步骤怎么重排序都不会影响到最终结果。
  重排序的结果只是造成了线程B拿到的是一个没有完全初始化完成的对象而已,可能这时候构造方法没有执行,拿到的对象属性可能是错误的,也有可能如果拿着这个没有完全初始化完成的对象去操作,可能会导致空指针的问题。
  所以,一般在使用DCL的时候会把变量声明为volatile,因为volatile的语义会禁止指令重排,而本质上就是加上了内存屏障。一切都是猜测
  如果依据这个解释,来回答群内提出的问题貌似也可以解释的通。
  因为map在put的时候可以不管new对象时候的指令重排,只要能拿到对象引用的内存地址就可以了,所以另外一个线程如果去get的话就可能拿到一个空值。
  从asifserial的语义来看,确实不会改变单线程内的执行结果,但是还有一点说的是只要数据没有依赖关系,就都可以重排序。问题的关键点在于put这个到底有依赖关系吗?依赖关系怎么定义?
  如果是最简单的比如x1,y2那么我们可以认为完全没有依赖关系,可以指令重排。如果是x1,yx1那么由于单线程内y依赖于x,所以不能指令重排。
  那么map。put(key,newB(value))呢?一道证明题
  Jcstress(JavaConcurrencyStress)是一个帮助测试JVM和硬件并发正确性的工具库。
  首先,先证明DCL的问题是否确实存在,是否真的在另外的线程中能看到未完全初始化的对象。代码如下:
  通过测试代码,如果最终能输出0,1,2,3那么代表确实是能拿到未完全初始化完成的对象。
  首先对代码mvncleaninstall打包,然后执行命令:javaXX:UseCompressedOopsXX:UnlockDiagnosticVMOptionsXX:CompileCommandprintcom。jcst。UnsafePublicationjcstress::callXX:CompileCommandinline,com。jcst。UnsafePublication::publishXX:PrintAssemblyjartargetjcstress。jarf1tUnsafePublicationvlog2。txt
  执行完成之后,查看输出结果发现问题确实存在:
  而且,通过生成的汇编指令,也可以看到发生了指令重排,引用被先赋值,对象还没有完全初始化完成。但是实际测试过程中,这个问题并不好复现,需要反复的测试才有可能拿到我们想要的结果。
  有了基础的事实之后,再继续修改代码,如果加上map操作还能出现这个现象的话,那么证明实际上map的put操作也是同样存在可能性的。
  如果同样我们能得到汇编的结果,put的操作也被指令重排发生在初始化完成之前的话,那么就可以证明我们的猜测了。
  结果和我们之前预料的不太一致,无论怎么修改代码顺序,测试脚本都是执行通过。这说明put不会把一个没有初始化完成的对象给保存进去。
  总结
  由于指令重排发生的场景非常多而且也非常底层,目前我们能看到的资料无非就告诉我们单线程结果不能改变,数据不能有依赖性,这样的话就能指令重排。
  而我们的代码从Java通过javac编译成字节码,再经过JIT动态编译成机器码,从机器码再经过处理器,到缓存这些过程都可能发生指令重排。而编译器、处理器、缓存这些根据机器、硬件环境不同,又都可能造成不同的影响。
  通过DCL的已知问题和最后根据jcstress得到汇编的结果来看,由于没有改变单线程最终结果,指令重排是确实发生了。但是从map的put的结果来看,最终结论是不会,put操作不会把一个没有初始化完成的对象保存进去。
  而我也尝试了不少其他的方式,比如打印、模拟map写了一个空方法,只是用到了引用对象,测试结果无一都是通过,所以大胆猜测使用了引用其实也是依赖的一种,这样就不会导致重排的发生。
  最后,如果你有更好的证实的方法,或者有不同的意见可以证实结论的错误性,欢迎拍砖打脸指正。
投诉 评论 转载

如懿传白蕊姬生下双性儿,母凭子贵梦破碎,幕后黑手藏的真好!《如懿传》中白蕊姬也是个可怜的角色,南府乐妓,身份低贱,得到太后的赏识送入宫中,一句曲有误,周郎顾成功飞上枝头。她最幸运的是怀上了皇上登基后的第一个孩子,这个孩子是贵子,……吴昕再次大哭,惹刘雯崩溃中国式巨婴,逼疯了多少人快乐家族最近似乎是非很多,继何炅牵手、谢娜缺席后,吴昕也冲上了热搜。前段时间,综艺《妈妈你真好看》开播,主打明星妈妈们的时尚改造,评委来头也不小超模刘雯。这个节目,吴昕也……细思极恐!凌晨3点,一裸男闯进全季酒店女住客房间1hr昨天,网名为fiore花花的女网友在网上哭诉:半夜三点,有一名男子光着身子闯入她的房间,自己受到了很大的惊吓,当时就被吓哭。她要求全季酒店给一个说法。虽……知名时尚杂志合作冯提莫,小主播逆袭成资源咖对于厂商来说什么最重要,那就是市场的影响力,最近时尚杂志《尼龙》三月企划已经发布,其中便有着冯提莫的位置。其实看到这个消息,想必很多人都不会感到惊讶,因为提到年度歌手的话……功夫一个真正的周星驰《功夫》这部电影结尾出现的字幕是这样的:主演周星驰;编剧周星驰;监制周星驰;导演周星驰从此以后,你再难看到一部,从头到尾拥有如此强烈的个人色彩的周星驰电影。《功夫》之后再无经典……限令出现,五位被父母强捧的星二代,没作品没演技应何去何从广电总是为人带来意想不到的惊喜,限籍令限娃令还有现在的限唯流量都是对部分明星的限制。而近期,国家广播电视总局也发布了消息,明确规定明星子女(成年)不得参与综艺与真人秀。……一次群聊引发的血案就在不久前,读者群因为一个提问引发了激烈的讨论!代码如下图:从问题来看,大家讨论的问题的焦点在于map去put一个对象的时候,究竟会不会因为对象没有完全初始化完成而……胡歌唐嫣合作新剧!!景天和紫萱这个搭配你们满意吗?娱乐聚焦八卦手册胡歌唐嫣合作新剧胡歌唐嫣浙江卫视9月23日举行秋季招商会现场曝光的招商片花中首次提及由王家卫监制、胡歌主演的电视剧《繁花》,马伊琍唐嫣辛芷蕾领衔主演……华晨宇前任爆料整容照片,并称张碧晨小三破坏感情四小时前微博一位名字为发发爱我2021用户爆料华晨宇照片,称华晨宇在医院整容时拍的照片,并称华晨宇整了鼻子,削骨,下巴,填充,还有皮肤修复华晨宇之前接受采访时还说,我不缺……长孙皇后强夺陆氏绝色未婚妻献给李世民唐朝贞观二年那会,长孙皇后正好在怀唐高宗李治。而当时唐太宗的后宫,除了表姐表妹,又有弟媳妇,又有寡妇,又有前朝公主,又有仇敌之女等等,当然成果还是相当不错的,还不到三十岁……锦心似玉迎来大结局,非会员未完全免费播放量就已达43。1亿《锦心似玉》大结局了徐令宜双厨狂喜家庭事业双丰收,儿女双全,爱情美满慕了慕了!舍不得小哇钟汉良啊戏外帮忙端水什么地笑死我了。锦心似玉非会员下个星期才会迎来大结局,现在已经……韩剧僵尸侦探男主身份成谜,他是谁?在韩剧《僵尸侦探》中,由演员崔振赫饰演的主角僵尸复活后,已经失去全部记忆,只能冒用偶然得到的金武英侦探身份,混迹于人群里。所以,因为失忆金武英理所当然的也不知道自己的真实……
演完陈情令演雪中悍刀行,明明是同一个人,愣是没认出来娱乐圈8大姐弟恋,最大相差16岁,其中一对简直是甜宠文范本12岁王诗龄分享私照,有了李湘当年的风范,家里另一处豪宅曝光不吹不黑,李幼斌一个眼神演出3个层次,黄景瑜让我想到火影鸣人广州二手房低于10万一个平方,普通人赚一个平方需要多少年她结婚了,她终于结婚了,知道她是谁吗?为了拿到1。08亿工资,郑爽连自己亲妈公司都告了刘诗诗喜得贵子,吴奇隆开心的合不拢嘴,网友的评论时代峰峻被约谈?鹿晗新剧?龚俊借机转型?李现热度?郑业成后续周海媚年轻时候有多绝?金庸愿为她改变周芷若结局,颜值惊艳时光天王嫂培训班出身?郭富城力挺的娇妻方媛靠这招打败熊黛林在成长需要抉择的时候,重读人生母爱无边作文范文600字女人滋润要滋阴滋阴养颜就靠吃出来中国风物黄芪补正劲爆!曝微软Win10将砍掉Edge上马Anaheim浏览器鸿运当头放客厅的好处成语《邯郸学步》的故事布谷鸟蛇果的种植环境市区飙车是主观心态还是过失心态改善肠道的生活技巧商机蒸发而来减肥难的原因是什么

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找七猫云易事利