最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java并發(fā)編程——volatile關(guān)鍵字

 更新時間:2020年10月09日 10:48:58   作者:莫斐銘  
這篇文章主要介紹了Java并發(fā)編程——volatile關(guān)鍵字的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)Java并發(fā)編程,感興趣的朋友可以了解下

一、volatile是什么

volatile是Java并發(fā)編程中重要的一個關(guān)鍵字,被比喻為“輕量級的synchronized”,與synchronized不同的是,volatile只能修飾變量,無法修飾方法及代碼塊等。
下面是使用volatile關(guān)鍵字實現(xiàn)的單例模式:

public class Singleton implements Serializable {
  private static volatile Singleton singleton;
  private Singleton() {}
  public static Singleton getSingleton() {
    if (singleton==null) {         // 1
      synchronized (Singleton.class) {  // 2
        if (singleton==null) {     // 3
          singleton = new Singleton();// 4
        }
      }
    }
    return singleton;
  }
  private Object readResolve() { //防止序列化破壞單例模式
    return singleton;
  }
}

1.單例為什么使用volatile關(guān)鍵字?

首先要理解new Singleton()做了什么。1.看class對象是否加載,如果沒有就進(jìn)行類的加載、解析和初始化;2.虛擬機分配內(nèi)存空間,初始化實例,3.調(diào)用構(gòu)造函數(shù),4.返回地址給引用。而cpu為了優(yōu)化程序,可能會進(jìn)行指令重排序,導(dǎo)致實例內(nèi)存還沒分配,就被使用了。

假設(shè)有兩個線程A和B,線程A執(zhí)行到new Singleton(),開始初始化實例對象,由于存在指令重排序,這次new操作,先把引用賦值了,還沒有執(zhí)行構(gòu)造函數(shù)(沒有真正執(zhí)行完)。這時時間片結(jié)束了,切換到線程B執(zhí)行,線程B調(diào)用new Singleton()方法,發(fā)現(xiàn)引用不等于null,就直接返回引用地址了,然后線程B執(zhí)行了一些操作,就可能導(dǎo)致線程B使用了還沒被初始化的變量。

2.單例模式中步驟1、2、3、4存在的意義何在?

首先,步驟2、3是保證單例。假設(shè)線程A和B都執(zhí)行到了步驟2,線程A拿到了鎖,執(zhí)行步驟3,如果此時沒有創(chuàng)建實例,線程A會執(zhí)行new創(chuàng)建實例,然后線程A釋放鎖,線程B拿到鎖,首先執(zhí)行步驟3,發(fā)現(xiàn)已經(jīng)創(chuàng)建了實例,直接返回。加鎖是比較消耗資源的,步驟1就是為了減少資源的消耗。

二、volatile的特性

1.禁止指令重排序

指令重排序是JVM為了優(yōu)化指令、提高程序運行效率,在不影響單線程程序執(zhí)行結(jié)果的前提下,盡可能地提高并行度。指令重排序包括編譯器重排序和運行時重排序。

volatile關(guān)鍵字提供內(nèi)存屏障的方式來防止指令被重排,編譯器在生成字節(jié)碼文件時,會在指令序列中插入內(nèi)存屏障來禁止特定類型的處理器重排序。

JVM內(nèi)存屏障插入策略:

  • 每個volatile寫操作的前面插入一個StoreStore屏障,Store1;StoreStore;Store2,在Store2及后續(xù)的寫入操作執(zhí)行前,保證Store1的寫入操作對其他處理器可見,保證了有序性和可見性;
  • 在每個volatile寫操作的后面插入一個StoreLoad屏障,Store1;StoreLoad;Load2,在Load2及后續(xù)的讀取操作執(zhí)行前,保證Store1的寫入操作對其他處理器可見,它的開銷是最大的,兼具其他三種的作用,保證了有序性和可見性;
  • 在每個volatile讀操作的后面插入一個LoadLoad屏障,Load1;LoadLoad;Load2,在Load2及后續(xù)的讀取操作執(zhí)行前,保證Load1讀取的數(shù)據(jù)已經(jīng)讀取完畢;
  • 在每個volatile讀操作的后面插入一個LoadStore屏障,Load1;LoadStore;Store2,在Store2及后續(xù)的寫入操作執(zhí)行前,保證Load1讀取的數(shù)據(jù)已經(jīng)讀取完畢。

2.保證內(nèi)存可見性

可見性是指對volatile變量的讀總能獲取其他任意線程對volatile變量的最后的寫。
可見性的實現(xiàn)基于volatile讀寫的內(nèi)存語義:

  • volatile寫的內(nèi)存語義:當(dāng)寫入一個volatile變量時,JVM將線程工作內(nèi)存中的變量值刷新到主內(nèi)存中;
  • volatile讀的內(nèi)存語義:當(dāng)讀取一個volatile變量時,JVM首先將改工作內(nèi)存中的變量設(shè)置為無效,重新從主內(nèi)存中獲取最新的有效值。

三、使用場景

(1)volatile是輕量級同步機制。與synchronized的區(qū)別是volatile只能保證有序性和可見性,不能保證原子性。
(2)volatile不能修飾寫入操作依賴當(dāng)前值的變量。聲明為volatile的簡單變量如果當(dāng)前值與該變量以前的值相關(guān),那么volatile關(guān)鍵字不起作用,也就是說如下的表達(dá)式都不是原子操作:“count++”、“count = count+1”。
(3)當(dāng)要訪問的變量已在synchronized代碼塊中,或為常量時,沒必要使用volatile;
(4)volatile保證了有序性,屏蔽掉了JVM中必要的代碼優(yōu)化,所以在效率上比較低,因此一定在必要時才使用此關(guān)鍵字。
(5)在以下兩個場景中可以使用volatile來代替synchronized:

  • 運算結(jié)果不依賴變量的當(dāng)前值,或者能夠確保只有單一的線程會修改變量的值。
  • 變量不需要與其他狀態(tài)變量共同參與不變約束。

以上就是淺析Java并發(fā)編程——volatile關(guān)鍵字的詳細(xì)內(nèi)容,更多關(guān)于Java并發(fā)編程——volatile關(guān)鍵字的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Springboot下swagger-ui.html訪問不到的解決方案

    Springboot下swagger-ui.html訪問不到的解決方案

    這篇文章主要介紹了Springboot下swagger-ui.html訪問不到的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • SpringBoot中HTTP請求不通的原因級解決方法

    SpringBoot中HTTP請求不通的原因級解決方法

    HTTP 請求是指從客戶端到服務(wù)器的請求消息,對于一個 Spring Boot 項目而言,服務(wù)器就是 Spring Boot,客戶端就是用戶本地的瀏覽器,但是會遇到SpringBoot HTTP請求不通的問題,本文介紹了一些常見問題及解決方法,需要的朋友可以參考下
    2025-02-02
  • java二維數(shù)組實現(xiàn)推箱子小游戲

    java二維數(shù)組實現(xiàn)推箱子小游戲

    這篇文章主要為大家詳細(xì)介紹了java二維數(shù)組實現(xiàn)推箱子小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • Java中的==使用方法詳解

    Java中的==使用方法詳解

    這篇文章主要給大家介紹了關(guān)于Java中的==使用方法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-09-09
  • 詳解Java并發(fā)工具類之CountDownLatch和CyclicBarrier

    詳解Java并發(fā)工具類之CountDownLatch和CyclicBarrier

    在JDK的并發(fā)包中,有幾個非常有用的并發(fā)工具類,它們分別是:CountDownLatch、CyclicBarrier、Semaphore和Exchanger,本文主要來講講其中CountDownLatch和CyclicBarrier的使用,感興趣的可以了解一下
    2023-06-06
  • 關(guān)于spring5的那些事:@Indexed 解密

    關(guān)于spring5的那些事:@Indexed 解密

    這篇文章主要介紹了關(guān)于spring5的那些事:@Indexed 解密,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • mybatis條件構(gòu)造器(EntityWrapper)的使用方式

    mybatis條件構(gòu)造器(EntityWrapper)的使用方式

    這篇文章主要介紹了mybatis條件構(gòu)造器(EntityWrapper)的使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 基于Hutool的圖片驗證碼功能模塊實現(xiàn)

    基于Hutool的圖片驗證碼功能模塊實現(xiàn)

    為了提高系統(tǒng)的安全性,防止接口被暴力刷新,驗證碼是個好的手段,圖片驗證碼沒有短信驗證碼的費用,其是個人開發(fā)者學(xué)習(xí)的重點,這篇文章主要介紹了基于Hutool的圖片驗證碼功能模塊實現(xiàn),需要的朋友可以參考下
    2022-10-10
  • Java中的@SneakyThrows注解詳解

    Java中的@SneakyThrows注解詳解

    這篇文章主要介紹了Java中的@SneakyThrows注解詳解,@SneakyThrows將當(dāng)前方法拋出的異常,包裝成RuntimeException,騙過編譯器,使得調(diào)用點可以不用顯示處理異常信息,需要的朋友可以參考下
    2023-10-10
  • Java初學(xué)者問題圖解(動力節(jié)點Java學(xué)院整理)

    Java初學(xué)者問題圖解(動力節(jié)點Java學(xué)院整理)

    本文通過圖文并茂的形式給大家介紹了java初學(xué)者問題,非常不錯,具有參考借鑒價值,需要的朋友參考下
    2017-04-04

最新評論

铁岭市| 芮城县| 津南区| 都安| 尚义县| 永丰县| 卓尼县| 双鸭山市| 鄂伦春自治旗| 龙岩市| 竹溪县| 利川市| 涪陵区| 吉隆县| 天水市| 凉山| 维西| 龙州县| 竹山县| 营口市| 蓝田县| 越西县| 田东县| 鹤峰县| 长治市| 马关县| 南靖县| 尚志市| 贵定县| 建宁县| 磴口县| 阳江市| 海淀区| 特克斯县| 花莲市| 美姑县| 大连市| 宜宾市| 启东市| 丹巴县| 肥西县|