成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java的synchronized 能防止指令重排序嗎?

開發(fā) 后端
「二狗」:二胖你昨天請假了是不是又去面試了啊?「二胖」:別說了我就出去試試水,看看現(xiàn)在工作好不好找,順帶出去找找打擊,然后才能好好靜下心來好好學(xué)習(xí)。

[[355420]]

 引言

「二狗」:二胖你昨天請假了是不是又去面試了啊?

「二胖」:別說了我就出去試試水,看看現(xiàn)在工作好不好找,順帶出去找找打擊,然后才能好好靜下心來好好學(xué)習(xí)。

「二狗:」 那被打擊的怎么樣啊?知道自己是什么樣的水平了吧,壞笑。

「二胖」:基礎(chǔ)太差,一面就讓回去等通知了,我要好好學(xué)習(xí)了,不跟你瞎扯了。

「二狗:」 都問了你什么問題啊,把你打擊成這樣?一起復(fù)盤下讓我也好好準(zhǔn)備下啊。

「二胖」:好吧,你既然這么好奇,那我就大概說下吧,你搬上小板凳仔細(xì)挺好了哦。我要開始我的表演了。

下面二胖第一面開始了。

「面試官」:二胖是吧,先做個自我介紹吧。

「二胖」:好的,我叫二胖,我來自長沙,今年25歲,從事java開發(fā)快3年了,現(xiàn)在在XX公司XX事業(yè)部擔(dān)任高級「java」開發(fā)工程師,主要負(fù)責(zé)XX系統(tǒng)。。。。。

「面試官」:好的,我看你簡歷上寫著熟練掌握并發(fā)編程你能跟我說說并發(fā)編程里面你都知道哪些關(guān)鍵字。

「二胖:」 這不就是要考我 synchronized 和volatile 這個我擅長啊,我特意背過的,synchronized 是java提供的一個關(guān)鍵字它主要能保證原子性、有序性它的底層主要是通過Monitor來實現(xiàn)的。volatile也是java的一個關(guān)鍵字它的主要作用是可以保證可見性。。。。此處省略1000字。

「面試官」:八股文背的不錯,說了這么多,我們來動手試試吧,寫一個雙重校驗鎖(dcl)的單例我看看。

「二胖:」 從屁股口袋里拿出了筆三下五除二就把它默寫出來了。

「面試官」:你有說道volatile關(guān)鍵字和synchronized關(guān)鍵字。synchronized可以保證原子性、有序性和可見性。而volatile卻只能保證有序性和可見性。那么,我們再來看一下雙重校驗鎖實現(xiàn)的單例,已經(jīng)使用了synchronized,為什么還需要volatile?這個volatile是否可以去掉?

「二胖:」 讓我想想,貌似好像確實可以去掉。

「面試官:」 我們今天的面試就到這里吧,后續(xù)有消息人事會聯(lián)系你,感謝你今天來面試。

二胖很郁悶回去谷歌了下這個問題,「stackoverflow」上也有這個問題,看樣子不只我一個人不知道這個問題嗎?看樣子面試掛的不冤「以上故事純屬虛構(gòu),如有雷同請以本文為主。」

synchronized 的有序性?

我們先來看看沒有加volatile 修飾的單例:

  1. public class Singleton {   
  2.     private static Singleton singleton;   
  3.      private Singleton (){}   
  4.      public static Singleton getSingleton() {   
  5.      if (singleton == null) {   
  6.          synchronized (Singleton.class) {   
  7.              if (singleton == null) {   
  8.                  singleton = new Singleton();   
  9.              }   
  10.           }   
  11.       }   
  12.       return singleton;   
  13.       }   
  14.   }   

上述代碼看下來是不是感覺沒啥問題。首先我們先來看下這一行代碼到底干了哪些事情

  1. singleton = new Singleton()  

上述過程我們可以簡化成3個步驟:

①「JVM」為對象分配一塊內(nèi)存M。

②在內(nèi)存M上為對象進(jìn)行初始化。

③將內(nèi)存M的地址復(fù)制給singleton變量。

這個步驟有兩種執(zhí)行順序可以按照 「①②③」或者「①③②」來執(zhí)行。當(dāng)我們按照「①③②」的順序來執(zhí)行的時候 我們假設(shè)有兩個線程ThreadA 和ThreadB 同時來請求Singleton.getSingleton方法:

正常情況按照 「①②③」的順序來執(zhí)行

「第一步:」ThreadA 進(jìn)入到第8行,執(zhí)行 singleton = new Singleton() 進(jìn)行對象的初始化(按照對象初始化的過程 「①②③」)執(zhí)行完。

「第二步:」 ThreadB進(jìn)入第5行判斷singleton不為空(第一步已經(jīng)初始化好了),直接返回singleton**第三步:**拿到這個對象做其他的操作。這樣看下來是不是沒有啥問題。

那如果對象初始化的時候按照 「①③②」 的步驟我們再來看看:「第一步:」 ThreadA進(jìn)入到第8行,執(zhí)行 singleton = new Singleton() 執(zhí)行完.①JVM為對象分配一塊內(nèi)存M。③將內(nèi)存的地址復(fù)制給singleton變量。

「第二步:」 此時ThreadB直接進(jìn)入第5行,發(fā)現(xiàn)singleton已經(jīng)不為空了然后直接就跳轉(zhuǎn)到12行拿到這個singleton返回去執(zhí)行操作去了。此時ThreadB拿到的singleton對象是個半成品對象,因為還沒有為這個對象進(jìn)行初始化(「②還沒執(zhí)行」)。「第三步:」 所以ThreadB拿到的對象去執(zhí)行方法可能會有異常產(chǎn)生。至于為什么會這樣列?《Java 并發(fā)編程實戰(zhàn)》有提到

有 synchronized 無 volatile 的 DCL(雙重檢查鎖) 會出現(xiàn)的情況:線程可能看到引用的當(dāng)前值,但對象的狀態(tài)值確少失效的,這意味著線程可以看到對象處于無效或錯誤的狀態(tài)。

說白了也就是ThreadB是可以拿到一個引用已經(jīng)有了但是內(nèi)存資源還沒有分配的對象。如果要解決創(chuàng)建對象按照①②③的順序,其實也就是為了解決指令重排只要第2行加個volatile修飾就好。

「說好的synchronized 不是可以保證有序性的嗎?volatile的有序性?synchronized 不能不夠保證指令重排嗎?」

怎么來定義順序呢?《深入理解Java虛擬機第三版》有提到

Java程序中天然的有序性可以總結(jié)為一句話:如果在本線程內(nèi)觀察,所有操作都是天然有序的。如果在一個線程中觀察另一個線程,所有操作都是無序的。前半句是指“線程內(nèi)似表現(xiàn)為串行的語義”,后半句是指“指令重排”現(xiàn)象和“工作內(nèi)存與主內(nèi)存同步延遲”現(xiàn)象。

  • 「synchronized」 的有序性是持有相同鎖的兩個同步塊只能串行的進(jìn)入,即被加鎖的內(nèi)容要按照順序被多個線程執(zhí)行,但是其內(nèi)部的同步代碼還是會發(fā)生重排序,使塊與塊之間有序可見。
  • 「volatile」的有序性是通過插入內(nèi)存屏障來保證指令按照順序執(zhí)行。不會存在后面的指令跑到前面的指令之前來執(zhí)行。是保證編譯器優(yōu)化的時候不會讓指令亂序。
  • 「synchronized 是不能保證指令重排的」。

結(jié)束

由于自己才疏學(xué)淺,難免會有紕漏,假如你發(fā)現(xiàn)了錯誤的地方,還望留言給我指出來,我會對其加以修正。

本文轉(zhuǎn)載自微信公眾號「 java金融」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系 java金融公眾號。

 

責(zé)任編輯:武曉燕 來源: java金融
相關(guān)推薦

2023-03-31 11:14:13

java虛擬機指令

2019-09-17 14:31:37

磁盤排序IO

2019-06-29 14:34:27

磁盤IO排序

2023-06-30 00:06:02

2022-06-08 13:54:23

指令重排Java

2022-05-05 07:38:32

volatilJava并發(fā)

2024-08-14 18:18:47

2017-05-10 16:01:39

推薦系統(tǒng)算法實踐

2025-03-10 08:00:00

RAG檢索Reranker

2019-01-29 14:25:39

2019-02-01 10:58:31

2010-06-21 10:09:47

Java

2023-03-01 08:38:35

volitale輕量版線程

2023-06-06 08:47:57

Java版管程編譯器

2020-05-28 07:50:18

重排序happens-befCPU

2025-03-26 00:55:00

2022-12-26 09:27:48

Java底層monitor

2023-04-10 10:32:00

模型排序

2025-03-20 06:48:55

性能優(yōu)化JDK

2021-01-14 08:58:12

Synchronize鎖操作
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 精品一二三区视频 | 日韩免费福利视频 | 日韩视频在线免费观看 | 亚洲网站在线观看 | 鲁视频| 91色网站 | 欧美性猛交一区二区三区精品 | 日韩欧美国产一区二区三区 | 久久综合久| 中文字幕在线一区二区三区 | 91久久久久久久久久久 | 欧美视频在线播放 | 国产成人精品免费视频大全最热 | 国产特级毛片 | 欧美日韩精品久久久免费观看 | 玖玖国产 | 亚洲午夜网 | 一区二区久久精品 | 国产精品欧美一区二区 | 涩涩操| 久久久99国产精品免费 | 天天综合日日夜夜 | 久久精品视频网站 | 免费在线a视频 | 国产成人a亚洲精品 | 午夜寂寞网站 | 韩三级在线观看 | 成人毛片在线观看 | 国产一区二区三区 | 成人亚洲一区 | 超碰成人免费 | 另类专区亚洲 | 国产一区二区三区在线 | 日韩在线观看视频一区 | 国产 91 视频 | 久久人| 在线观看久草 | 国产精品日韩高清伦字幕搜索 | 日韩中文在线视频 | 91资源在线观看 | 国产在线观看一区二区 |