" />

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

Java Volatile關鍵字你真的了解嗎

 更新時間:2021年12月21日 17:17:32   作者:mikechen的互聯網架構  
這篇文章主要為大家介紹了Java Volatile關鍵字,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

正文

在談 Volatile 之前,我們先回顧下 Java 內存模型 的三要素:原子性、可見性、有序性,也就是大家常提到的并發(fā)編程三要素。

并發(fā)編程的三要素

1.原子性

和數據庫事務中的原子性一樣,滿足原子性特性的操作是不可中斷的,要么全部執(zhí)行成功要么全部執(zhí)行失敗。

只有簡單的讀取、賦值(而且必須是將數字賦值給某個變量,變量之間的相互賦值不是原子操作)才是原子操作。

比如:

i = 2;j = i;i++;i = i + 1;

上面4個操作中,i=2是讀取操作,必定是原子性操作,j=i你以為是原子性操作,其實吧,分為兩步,一是讀取i的值,然后再賦值給j,這就是2步操作了,稱不上原子操作,i++和i = i + 1其實是等效的,讀取i的值,加1,再寫回主存,那就是3步操作了。

所以上面的舉例中,最后的值可能出現多種情況,就是因為滿足不了原子性。

非原子操作都會存在線程安全問題,需要我們使用同步技術(sychronized)來讓它變成一個原子操作,java的concurrent包下提供了一些原子類:比如:AtomicIntegerAtomicLong等。

2.可見性

多個線程訪問同一個共享變量時,其中一個線程對這個共享變量值的修改,其他線程能夠立刻獲得修改以后的值。

3.有序性

編譯器和處理器為了優(yōu)化程序性能而對指令序列進行重排序,也就是你編寫的代碼順序和最終執(zhí)行的指令順序是不一致的。但是重排序過程不會影響到單線程程序的執(zhí)行,卻會影響到多線程并發(fā)執(zhí)行的正確性。

Volatile

Volatile?是一個Java語言的類型修飾符,一旦一個共享變量(類的成員變量、類的靜態(tài)成員變量)被Volatile修飾之后,那么就具備了兩層語義:

1、保證多線程下的可見性

2、禁止進行指令重排序(即保證有序性)

這里需要注意一個問題,Volatile 只能讓被他修飾內容具有可見性、有序性 。Volatile只能保證對單次讀/寫的原子性,i++ 這種操作不能保證原子性。

Volatile 的內存模型

Volatile 的內存模型

**Java 內存模型(JMM)**是一種抽象的概念,并不真實存在,它描述了一組規(guī)則或規(guī)范,通過這組規(guī)范定義了程序中各個變量(包括實例字段、靜態(tài)字段和構成數組對象的元素)的訪問方式。

試圖屏蔽各種硬件和操作系統(tǒng)的內存訪問差異,以實現讓 Java 程序在各種平臺下都能達到一致的內存訪問效果。

Java內存模型規(guī)定了所有的變量都存儲在主內存中,每條線程還有自己的工作內存,線程的工作內存中保存了該線程中是用到的變量的主內存副本拷貝,線程對變量的所有操作都必須在工作內存中進行,而不能直接讀寫主內存。不同的線程之間也無法直接訪問對方工作內存中的變量,線程間變量的傳遞均需要自己的工作內存和主存之間進行數據同步進行。

  • 主內存?主要存儲的是Java實例對象,所有線程創(chuàng)建的實例對象都存放在主內存中,不管該實例對象是成員變量還是方法中的本地變量(也稱局部變量),當然也包括了共享的類信息、常量、靜態(tài)變量。由于是共享數據區(qū)域,多條線程對同一個變量進行訪問可能會發(fā)現線程安全問題。
  • 工作內存?每條線程都有自己的工作內存(Working Memory,又稱本地內存,可與前面介紹的處理器高速緩存類比),線程的工作內存中保存了該線程使用到的變量的主內存中的共享變量的副本拷貝。

工作內存是 JMM 的一個抽象概念,并不真實存在 。它涵蓋了緩存,寫緩沖區(qū),寄存器以及其他的硬件和編譯器優(yōu)化。

主要存儲當前方法的所有本地變量信息(工作內存中存儲著主內存中的變量副本拷貝),每個線程只能訪問自己的工作內存,即線程中的本地變量對其它線程是不可見的,就算是兩個線程執(zhí)行的是同一段代碼,它們也會各自在自己的工作內存中創(chuàng)建屬于當前線程的本地變量,當然也包括了字節(jié)碼行號指示器、相關Native方法的信息。

Volatile 的實現原理

Volatile 保證內存可見性

Volatile 的實現原理

主內存和工作內存之間的交互有具體的交互協議,JMM定義了?八種操作?來完成,這八種操作是 原子的 、 不可再分的 ,它們分別是:lockunlock,read,load,use,assign,store,write

其中,lock , unlock , read , write 作用于主內存; load ,use , assign , store 作用于工作內存。

(1) lock

將主內存中的變量鎖定,為一個線程所獨占。

(2) unclock

將lock加的鎖定解除,此時其它的線程可以有機會訪問此變量。

(3) read

將主內存中的變量值讀到工作內存當中。

(4) load

將read讀取的值保存到工作內存中的變量副本中。

(5) use

將值傳遞給線程的代碼執(zhí)行引擎。

(6) assign

將執(zhí)行引擎處理返回的值重新賦值給變量副本。

(7) store

將變量副本的值存儲到主內存中。

(8) write

將 store 存儲的值寫入到主內存的共享變量當中。

  • 從主存復制變量到當前工作內存(read and load)
  • 執(zhí)行代碼,改變共享變量值 (use and assign)
  • 用工作內存數據刷新主存相關內容 (store and write)

指令規(guī)則

  • read 和 load、store 和 write 必須成對出現。
  • assign 操作,工作內存變量改變后必須刷回主內存。
  • 同一時間只能運行一個線程對變量進行 lock,當前線程 lock 可重入,unlock 次數必須等于 lock 的次數,該變量才能解鎖。
  • 對一個變量 lock 后,會清空該線程工作內存變量的值,重新執(zhí)行 load 或者 assign 操作初始化工作內存中變量的值。
  • unlock 前,必須將變量同步到主內存( store/write 操作)。

Volatile源碼案例

Volatile源碼案例

總結

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注腳本之家的更多內容!

相關文章

  • SpringBoot整合Hashids實現數據ID加密隱藏的全過程

    SpringBoot整合Hashids實現數據ID加密隱藏的全過程

    這篇文章主要為大家詳細介紹了SpringBoot整合Hashids實現數據ID加密隱藏的全過程,文中的示例代碼講解詳細,對大家的學習或工作有一定的幫助,感興趣的小伙伴可以跟隨小編一起學習一下
    2024-01-01
  • Spring中自定義數據類型轉換的方法詳解

    Spring中自定義數據類型轉換的方法詳解

    Spring3引入了一個core.onvert包,提供一個通用類型轉換系統(tǒng)。在Spring容器中,可以使用這個系統(tǒng)作為PropertyEditor實現的替代,將外部化的bean屬性值字符串轉換為所需的屬性類型。本文將詳解這一系統(tǒng)的使用方法,需要的可以參考一下
    2022-06-06
  • JavaWeb登陸功能實現代碼

    JavaWeb登陸功能實現代碼

    這篇文章主要為大家詳細介紹了JavaWeb登陸功能實現代碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • java控制臺版實現五子棋游戲

    java控制臺版實現五子棋游戲

    這篇文章主要為大家詳細介紹了java控制臺版實現五子棋游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • Mybatis圖文并茂講解分頁插件

    Mybatis圖文并茂講解分頁插件

    使用過mybatis的人都知道,mybatis本身就很小且簡單,sql寫在xml里,統(tǒng)一管理和優(yōu)化。缺點當然也有,比如我們使用過程中,要使用到分頁,如果用最原始的方式的話,1.查詢分頁數據,2.獲取分頁長度,也就是說要使用到兩個方法才能完成分頁
    2022-07-07
  • JavaSE實現圖書管理系統(tǒng)的示例代碼

    JavaSE實現圖書管理系統(tǒng)的示例代碼

    這篇博客是在學習了一部分Java基礎語法之后的練習項目,通過這個小項目的練習,對Java中的類和對象,抽象類和接口等進行熟悉理解??旄S小編一起學習學習吧
    2022-08-08
  • 給JavaBean賦默認值并且轉Json字符串的實例

    給JavaBean賦默認值并且轉Json字符串的實例

    這篇文章主要介紹了給JavaBean賦默認值并且轉Json字符串的實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 從application.properties配置文件獲取的漢字亂碼的解決方法

    從application.properties配置文件獲取的漢字亂碼的解決方法

    平時從配置文件各種讀取配置參數都正常,但是有時候放了個中文就亂碼,你肯定試過網上好多方法,都沒解決,那么來看下面,恭喜你終于找這里了,本文給大家介紹了從application.properties配置文件獲取的漢字亂碼的解決方法,需要的朋友可以參考下
    2024-03-03
  • 每日六道java新手入門面試題,通往自由的道路--線程池

    每日六道java新手入門面試題,通往自由的道路--線程池

    這篇文章主要為大家分享了最有價值的6道線程池面試題,涵蓋內容全面,包括數據結構和算法相關的題目、經典面試編程題等,對hashCode方法的設計、垃圾收集的堆和代進行剖析,感興趣的小伙伴們可以參考一下
    2021-06-06
  • 使用Swagger實現接口版本號管理方式

    使用Swagger實現接口版本號管理方式

    這篇文章主要介紹了使用Swagger實現接口版本號管理方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10

最新評論