" />

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

Java Volatile關(guān)鍵字你真的了解嗎

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

正文

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

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

1.原子性

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

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

比如:

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

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

所以上面的舉例中,最后的值可能出現(xiàn)多種情況,就是因?yàn)闈M足不了原子性。

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

2.可見性

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

3.有序性

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

Volatile

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

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

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

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

Volatile 的內(nèi)存模型

Volatile 的內(nèi)存模型

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

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

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

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

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

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

Volatile 的實(shí)現(xiàn)原理

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

Volatile 的實(shí)現(xiàn)原理

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

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

(1) lock

將主內(nèi)存中的變量鎖定,為一個(gè)線程所獨(dú)占。

(2) unclock

將lock加的鎖定解除,此時(shí)其它的線程可以有機(jī)會(huì)訪問此變量。

(3) read

將主內(nèi)存中的變量值讀到工作內(nèi)存當(dāng)中。

(4) load

將read讀取的值保存到工作內(nèi)存中的變量副本中。

(5) use

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

(6) assign

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

(7) store

將變量副本的值存儲(chǔ)到主內(nèi)存中。

(8) write

將 store 存儲(chǔ)的值寫入到主內(nèi)存的共享變量當(dāng)中。

  • 從主存復(fù)制變量到當(dāng)前工作內(nèi)存(read and load)
  • 執(zhí)行代碼,改變共享變量值 (use and assign)
  • 用工作內(nèi)存數(shù)據(jù)刷新主存相關(guān)內(nèi)容 (store and write)

指令規(guī)則

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

Volatile源碼案例

Volatile源碼案例

總結(jié)

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

相關(guān)文章

  • SpringBoot整合Hashids實(shí)現(xiàn)數(shù)據(jù)ID加密隱藏的全過程

    SpringBoot整合Hashids實(shí)現(xiàn)數(shù)據(jù)ID加密隱藏的全過程

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

    Spring中自定義數(shù)據(jù)類型轉(zhuǎn)換的方法詳解

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

    JavaWeb登陸功能實(shí)現(xiàn)代碼

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

    java控制臺(tái)版實(shí)現(xiàn)五子棋游戲

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

    Mybatis圖文并茂講解分頁(yè)插件

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

    JavaSE實(shí)現(xiàn)圖書管理系統(tǒng)的示例代碼

    這篇博客是在學(xué)習(xí)了一部分Java基礎(chǔ)語(yǔ)法之后的練習(xí)項(xiàng)目,通過這個(gè)小項(xiàng)目的練習(xí),對(duì)Java中的類和對(duì)象,抽象類和接口等進(jìn)行熟悉理解??旄S小編一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • 給JavaBean賦默認(rèn)值并且轉(zhuǎn)Json字符串的實(shí)例

    給JavaBean賦默認(rèn)值并且轉(zhuǎn)Json字符串的實(shí)例

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

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

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

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

    這篇文章主要為大家分享了最有價(jià)值的6道線程池面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,對(duì)hashCode方法的設(shè)計(jì)、垃圾收集的堆和代進(jìn)行剖析,感興趣的小伙伴們可以參考一下
    2021-06-06
  • 使用Swagger實(shí)現(xiàn)接口版本號(hào)管理方式

    使用Swagger實(shí)現(xiàn)接口版本號(hào)管理方式

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

最新評(píng)論