中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java面試官最喜歡問的關鍵字之volatile詳解

發布時間:2020-08-21 16:40:32 來源:腳本之家 閱讀:170 作者:半畝方田 欄目:編程語言

前言

筆者去年面試過幾家公司,基本上每家公司都會問到volatile,甚至有的公司每輪面試的時候都會問到。面試官這么喜歡問volatile就是因為這個關鍵字涉及到的知識點較多比如Java內存模型、內存屏障、happen-befor等知識,可以繼續挖掘到系統指令、超線程等知識。

Java內存模型(JMM)

volatile是Java虛擬機提供的最輕量的同步機制,但很難被正確的理解與使用,通過學習Java內存模型對volatile專門定義的一些特殊訪問規則,或許會對理解volatile有一定幫助。

Java內存模型定義了線程和內存之間關系:線程之間的共享變量存儲在主內存中,每個線程都有一個私有的本地內存,本地內存中存儲了該線程以讀 / 寫共享變量的副本。本地內存是 JMM 的一個抽象概念,并不真實存在;它涵蓋內存、緩存、寄存器以及其他的硬件和編譯器優化。Java的內存模型抽象如下:

Java面試官最喜歡問的關鍵字之volatile詳解

volatile的語義

volatile主要提供了兩種語義:

1,可見性:

可見性是指一個線程寫入的值,其他線程能夠立即讀取。在由Java內存模型可知道,每個線程都是有本地內存。所以線程A寫入在正常情況下,線程B不能立即讀取。但是在volatile變量,可以保證線程A不寫入本地內存直接寫入主內存,線程B直接從主內存中讀取,不從本地內存中讀取。

2,禁止指令重排序:

重排序是指編譯器和處理器為了優化程序性能而對指令進行重排序的一種優化手段。

Java面試官最喜歡問的關鍵字之volatile詳解

Java程序的幾種重排序

  • 編譯器優化重排序:編譯器在不改變單線程程序語義的前提下,可以重新安排語句的執行順序。
  • 指令級并行的重排序:如果不存在數據依賴性,處理器可以改變語句對應機器指令的執行順序。
  • 內存系統的重排序:處理器使用緩存和讀寫緩沖區,這使得加載和存儲操作看上去可能是在亂序執行

volatile的技術基石--內存屏障

內存屏障是cpu指令,該指令保證特定操作的順序性和某些內存的可見性。插入一條內存屏障指令之后會告訴編譯器和CPU:不管什么指令都不能和這條指令重排序。內存屏障所做的另外一件事情就是強制刷出各種CPU cache,如一個Write-Barrier(寫入屏障)將刷出所有在Barrier之前寫入cache的數據,因此,任何CPU上的線程都能讀取到這些數據的最新版本。

對于Java程序而言,如果把加入volatile關鍵字的代碼和未加入volatile關鍵字的代碼都生成匯編代碼,會發現加入volatile關鍵字的代碼會多出一個lock前綴指令。

volatile的典型用例

狀態標志,代碼示例如下:

Java面試官最喜歡問的關鍵字之volatile詳解

線程1執行run()的過程中,可能有另外的線程2調用了shutdown,所以stop變量必須是volatile(利用的volatile的可見性)。

還有一種常見的用法在雙重檢驗的單例實現上,代碼如下:

Java面試官最喜歡問的關鍵字之volatile詳解

instance = new Singleton()這句,這并非是一個原子操作,事實上在 JVM 中這句話大概做了下面 3 件事情:

  • 給 instance 分配內存
  • 調用 Singleton 的構造函數來初始化成員變量
  • 將instance對象指向分配的內存空間(執行完這步 instance 就為非 null 了)

如果instance變量沒有加volatile,因為指令重排序的存在,就可能導致執行步驟是1-2-3,也可能是1-3-2。一旦是1-3-2,就可能會導致訪問未初始化的內存。但是加上volatile關鍵字之后,一定保證是按照1-2-3步驟執行的(利用的volatile的禁止重排序)。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

佛坪县| 于田县| 招远市| 通道| 当雄县| 海兴县| 贵定县| 灵丘县| 望都县| 易门县| 仪征市| 温泉县| 仁化县| 陵川县| 中方县| 黎城县| 资溪县| 伽师县| 昌平区| 东平县| 辉县市| 赫章县| 民乐县| 叶城县| 石家庄市| 亳州市| 嵊州市| 七台河市| 许昌市| 永定县| 铜陵市| 鸡泽县| 伊通| 凤冈县| 嵊泗县| 扎鲁特旗| 柏乡县| 昭觉县| 罗源县| 澄城县| 临海市|