青蛙见了蜈蚣,好奇地问:"蜈蚣大哥,我很好奇,你那么多条腿,走路的时候先迈哪一条啊?"
蜈蚣听后说:"青蛙老弟,我一直就这么走路,从没想过先迈哪一条腿,等我想一想再回答你。"
蜈蚣站立了几分钟,它一边思考一边向前,蹒跚了几步,终于趴下去了。
它对青蛙说:“请你再也别问其它蜈蚣这个问题了!我一直都在这样走路,这根本不成问题!可现在你问我先移动哪一条腿,我也不知道了。搞得我现在连路都不会走了,我该怎么办呢?”
这个小故事属实反映了我最近的心态:
越学越不会了。。。
本来synchronized
和volatile
关键字用得好好的,我非要深入研究一下他们的原理,所以研究了内存屏障,又研究了和内存屏障相关的MESI
,又研究了Cache Coherence
和Memory Consistency
,发现一切问题都出在CPU身上。于是又惊叹Java一次编写到处运行的特性,最终又研究到JMM
。
说是研究,其实就是把学习过程中自己抛出来的问题解决掉,把所有知识穿成一条线罢了。
这条线的线头就从指令的乱序执行开始了。
经典的指令乱序执行的原因有两种,分别是Compiler Reordering和CPU Reordering。
编译器会对高级语言的代码进行分析,如果它认为你的代码可以优化,那么他会对你的代码进行各种优化然后生成汇编指令。当然,本文说的优化主要是指令重排(Compiler Reordering)。
但是编译器的优化必须满足特定的条件,一个非常重要的原则就是as-if-serial
语义:
Allows any and all code transformations that do not change the observable behavior of the program.
编译器必须遵守as-if-serial
语义,也就是编译器不会对存在数据依赖关系的操作做重排序,因为这种重排序会改变执行结果。 但是,如果操作之间不存在数据依赖关系ÿ