欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java面試官最喜歡問的關(guān)鍵字之volatile詳解

 更新時間:2019年03月19日 15:38:08   作者:半畝方田  
這篇文章主要給大家介紹了關(guān)于Java面試官最喜歡問的關(guān)鍵字之volatile的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Java具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧

前言

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

Java內(nèi)存模型(JMM)

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

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

volatile的語義

volatile主要提供了兩種語義:

1,可見性:

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

2,禁止指令重排序:

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

Java程序的幾種重排序

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

volatile的技術(shù)基石--內(nèi)存屏障

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

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

volatile的典型用例

狀態(tài)標志,代碼示例如下:


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

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

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

  • 給 instance 分配內(nèi)存
  • 調(diào)用 Singleton 的構(gòu)造函數(shù)來初始化成員變量
  • 將instance對象指向分配的內(nèi)存空間(執(zhí)行完這步 instance 就為非 null 了)

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

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。

相關(guān)文章

  • SpringBoot Admin 使用指南(推薦)

    SpringBoot Admin 使用指南(推薦)

    這篇文章主要介紹了SpringBoot Admin 使用指南(推薦),Spring Boot Admin 是一個管理和監(jiān)控你的 Spring Boot 應用程序的應用程序,非常具有實用價值,需要的朋友可以參考下
    2018-01-01
  • java文件上傳Demo(必看篇)

    java文件上傳Demo(必看篇)

    下面小編就為大家?guī)硪黄猨ava文件上傳Demo(必看篇)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • SpringBoot+RabbitMQ實現(xiàn)消息可靠傳輸詳解

    SpringBoot+RabbitMQ實現(xiàn)消息可靠傳輸詳解

    消息的可靠傳輸是面試必問的問題之一,保證消息的可靠傳輸主要在生產(chǎn)端開啟?comfirm?模式,RabbitMQ?開啟持久化,消費端關(guān)閉自動?ack?模式。本文將詳解SpringBoot整合RabbitMQ如何實現(xiàn)消息可靠傳輸,需要的可以參考一下
    2022-05-05
  • mybatis中映射文件(mapper)中的使用規(guī)則

    mybatis中映射文件(mapper)中的使用規(guī)則

    這篇文章主要介紹了mybatis中映射文件(mapper)中的使用規(guī)則,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java 封裝基礎知識

    Java 封裝基礎知識

    這篇文章主要介紹了Java 封裝的相關(guān)資料,文中示例代碼非常詳細,幫助大家更好的理解和學習,感興趣的朋友可以了解下
    2020-07-07
  • Java實現(xiàn)求二叉樹的深度和寬度

    Java實現(xiàn)求二叉樹的深度和寬度

    這篇文章主要介紹了Java實現(xiàn)求二叉樹的深度和寬度,本文分別給出代碼實例,需要的朋友可以參考下
    2015-06-06
  • Java數(shù)據(jù)結(jié)構(gòu)實現(xiàn)二維數(shù)組與稀疏數(shù)組轉(zhuǎn)換詳解

    Java數(shù)據(jù)結(jié)構(gòu)實現(xiàn)二維數(shù)組與稀疏數(shù)組轉(zhuǎn)換詳解

    稀疏數(shù)組是用于優(yōu)化,壓縮具有以下特點的二維數(shù)組:當二維數(shù)組中的元素大部分相同,有意義的數(shù)據(jù)元素較少時,可以使用稀疏數(shù)組進行簡化,節(jié)省存儲空間
    2021-10-10
  • Java基礎類學習之String詳解

    Java基礎類學習之String詳解

    這篇文章主要為大家詳細介紹了Java基礎類中String的相關(guān)知識,文中的示例代碼講解詳細,對我們學習Java有一定的幫助,需要的可以參考一下
    2022-12-12
  • SpringBoot如何獲取Kafka的Topic列表

    SpringBoot如何獲取Kafka的Topic列表

    這篇文章主要介紹了SpringBoot如何獲取Kafka的Topic列表問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • Mybatis-Plus實現(xiàn)自定義SQL具體方法

    Mybatis-Plus實現(xiàn)自定義SQL具體方法

    Mybatis-Plus是Mybatis的一個增強工具,它可以優(yōu)化我們的開發(fā)效率,這篇文章主要介紹了Mybatis-Plus實現(xiàn)自定義SQL,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-08-08

最新評論