原子性、可見(jiàn)性與有序性

原子性

原子性是指一個(gè)操作是不可中斷的。即使是在多個(gè)線程一起執(zhí)行的時(shí)候,一個(gè)操作一旦開(kāi)始,就不會(huì)被其它線程干擾。

由 Java 內(nèi)存模型直接保證的原子性變量操作包括 read、load、assign、use、store 和 write,我們大致可以認(rèn)為基本數(shù)據(jù)類型的訪問(wèn)讀寫(xiě)是具備原子性的(例外就是 long 和 double 的非原子性協(xié)定)。

盡管虛擬機(jī)未把 lock 和 unlock 操作直接開(kāi)放給用戶使用,但是卻提供了更高層次的字節(jié)碼指令monitorenter 和 monitorexit 來(lái)隱式地使用這兩個(gè)操作,這兩個(gè)字節(jié)碼指令反映到 Java 代碼中就是同步塊——synchronized 關(guān)鍵字,因此在 synchronized 塊之間的操作也具備原子性。

可見(jiàn)性

可見(jiàn)性(Visibility):可見(jiàn)性是指當(dāng)一個(gè)線程修改了共享變量的值,其他線程能夠立即得知這個(gè)修改。

除了 volatile 以外,Java 還有兩個(gè)關(guān)鍵字能實(shí)現(xiàn)可見(jiàn)性,即 synchronized 和 final

  • 同步塊的可見(jiàn)性是由「對(duì)一個(gè)變量執(zhí)行 unlock 操作之前,必須先把此變量同步回主內(nèi)存中(執(zhí)行 store、write 操作)」這條規(guī)則獲得的,
  • final 關(guān)鍵字的可見(jiàn)性是指:保證一個(gè)對(duì)象的構(gòu)建方法結(jié)束前,所有 final 成員變量都必須完成初始化(前提是沒(méi)有 this 引用溢出)。在構(gòu)造器中一旦初始化完成,并且構(gòu)造器沒(méi)有把「this」的引用傳遞出去,那在其他線程中就能看見(jiàn) final 字段的值。
    • this 引用逃逸 是指在構(gòu)造函數(shù)返回之前其他線程就持有該對(duì)象的引用。調(diào)用尚未構(gòu)造完全的對(duì)象的方法可能引發(fā)令人疑惑的錯(cuò)誤, 因此應(yīng)該避免 this 逃逸的發(fā)生。
      • 例子:在構(gòu)造函數(shù)中啟動(dòng)線程 / 注冊(cè)監(jiān)聽(tīng)器/ 創(chuàng)建匿名內(nèi)部類。

有序性

如果在本線程內(nèi)觀察,所有的操作都是有序的;如果在一個(gè)線程中觀察另一個(gè)線程,所有的操作都是無(wú)序的。前半句是指「線程內(nèi)表現(xiàn)為串行的語(yǔ)義」(Within-Thread As-If-Serial Semantics),后半句是指「指令重排序」現(xiàn)象和「工作內(nèi)存與主內(nèi)存同步延遲」現(xiàn)象。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容