一道大题决定去留:为什么synchronized无法禁止指令重排,却能保证有序性?
△Hollis, 一個(gè)對(duì)Coding有著獨(dú)特追求的人△
這是Hollis的第?253篇原創(chuàng)分享
作者 l Hollis
來(lái)源 l Java之道(ID:javaways)
前幾天有一位讀者找我問(wèn)一個(gè)問(wèn)題,說(shuō)是這道題可能影響了他接下來(lái)3年的技術(shù)成長(zhǎng)。
據(jù)說(shuō)這位讀者前面的很多問(wèn)題會(huì)的都還可以,屬于那種可過(guò)可不過(guò)的類型的,面試官出了最后一道題,就是回答的滿意就可以給Offer,回答的不好就不讓過(guò)的意思。
那么這道題到底應(yīng)該如何回答呢?
首先我們要分析下這道題,不得不說(shuō)這個(gè)面試官還是有一定的水平的,這簡(jiǎn)單的一個(gè)問(wèn)題,其實(shí)里面還是包含了很多信息的,要想回答好這個(gè)問(wèn)題,面試者至少要知道一下概念:
Java內(nèi)存模型、并發(fā)編程有序性問(wèn)題、指令重排、synchronized鎖、可重入鎖、排它鎖、as-if-serial語(yǔ)義、單線程&多線程
所以,這道題的正確回答姿勢(shì)是怎樣的呢?
標(biāo)準(zhǔn)答案如下:
這是個(gè)好問(wèn)題,這個(gè)問(wèn)題我曾經(jīng)也思考過(guò),也查閱過(guò)很多資料,甚至還去看過(guò)hotsopt的源碼。
不管三七二十一,上來(lái)先舔一波,然后表示下自己求知好學(xué)的態(tài)度。
為了進(jìn)一步提升計(jì)算機(jī)各方面能力,在硬件層面做了很多優(yōu)化,如處理器優(yōu)化和指令重排等,但是這些技術(shù)的引入就會(huì)導(dǎo)致有序性問(wèn)題。
先告訴面試官你知道什么是有序性問(wèn)題,也知道是什么原因?qū)е碌挠行蛐詥?wèn)題
我們也知道,最好的解決有序性問(wèn)題的辦法,就是禁止處理器優(yōu)化和指令重排,就像volatile中使用內(nèi)存屏障一樣。
表明你知道啥是指令重排,也知道他的實(shí)現(xiàn)原理
但是,雖然很多硬件都會(huì)為了優(yōu)化做一些重排,但是在Java中,不管怎么排序,都不能影響單線程程序的執(zhí)行結(jié)果。這就是as-if-serial語(yǔ)義,所有硬件優(yōu)化的前提都是必須遵守as-if-serial語(yǔ)義。
重點(diǎn)!解釋下什么是as-if-serial語(yǔ)義,因?yàn)檫@是這道題的第一個(gè)關(guān)鍵詞,答上來(lái)就對(duì)了一半了
再說(shuō)下synchronized,他是Java提供的鎖,可以通過(guò)他對(duì)Java中的對(duì)象加鎖,并且他是一種排他的、可重入的鎖。
裝X項(xiàng),不留痕跡的展示自己對(duì)鎖了解的比較多
所以,當(dāng)某個(gè)線程執(zhí)行到一段被synchronized修飾的代碼之前,會(huì)先進(jìn)行加鎖,執(zhí)行完之后再進(jìn)行解鎖。在加鎖之后,解鎖之前,其他線程是無(wú)法再次獲得鎖的,只有這條加鎖線程可以重復(fù)獲得該鎖。
介紹synchronized的原理,這是本題的第二個(gè)關(guān)鍵點(diǎn),到這里基本就可以拿滿分了。
synchronized通過(guò)排他鎖的方式就保證了同一時(shí)間內(nèi),被synchronized修飾的代碼是單線程執(zhí)行的。所以呢,這就滿足了as-if-serial語(yǔ)義的一個(gè)關(guān)鍵前提,那就是單線程,因?yàn)橛衋s-if-serial語(yǔ)義保證,單線程的有序性就天然存在了。
最后總結(jié)一下問(wèn)題,給面試官致命一擊!Offer到手!~
關(guān)于作者:Hollis,一個(gè)對(duì)Coding有著獨(dú)特追求的人,現(xiàn)任阿里巴巴技術(shù)專家,個(gè)人技術(shù)博主,技術(shù)文章全網(wǎng)閱讀量數(shù)千萬(wàn),《程序員的三門(mén)課》聯(lián)合作者。
- MORE | 更多精彩文章 -
這家全球最大的成人網(wǎng)站,保存著西方媒體最后的良心
程序員需要了解依賴沖突的原因以及解決辦法
【阿里內(nèi)推006期】浙江網(wǎng)商銀行急需資深JAVA開(kāi)發(fā)工程師/技術(shù)專家、數(shù)據(jù)技術(shù)專家
你還在代碼里做讀寫(xiě)分離么,試試這個(gè)中間件吧!
如果你喜歡本文,
請(qǐng)長(zhǎng)按二維碼,關(guān)注?Hollis.
轉(zhuǎn)發(fā)至朋友圈,是對(duì)我最大的支持。
好文章,我在看??
總結(jié)
以上是生活随笔為你收集整理的一道大题决定去留:为什么synchronized无法禁止指令重排,却能保证有序性?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 关于损失函数的一些个人理解
- 下一篇: 如何理解神经网络优化中Momentem能