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

Java并發(fā)編程-volatile可見性詳解

 更新時(shí)間:2019年03月22日 11:30:42   作者:尋箏  
這篇文章主要介紹了Java并發(fā)編程-volatile可見性詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

要學(xué)習(xí)好Java的多線程,就一定得對(duì)volatile關(guān)鍵字的作用機(jī)制了熟于胸。最近博主看了大量關(guān)于volatile的相關(guān)博客,對(duì)其有了一點(diǎn)初步的理解和認(rèn)識(shí),下面通過自己的話敘述整理一遍。

有什么用?

volatile主要對(duì)所修飾的變量提供兩個(gè)功能

可見性
防止指令重排序
<br>本篇博客主要對(duì)volatile可見性進(jìn)行探討,以后發(fā)表關(guān)于指令重排序的博文。

什么是可見性?

把JAVA內(nèi)存模型(JMM)展示得很詳細(xì)了,簡單概括一下

1.每個(gè)Thread有一個(gè)屬于自己的工作內(nèi)存(可以理解為每個(gè)廚師有一個(gè)屬于自己的鐵鍋)
2.所有Thread共用一個(gè)主內(nèi)存(餐廳所有的廚師共用同一個(gè)冰箱)
3.每個(gè)Thread操作數(shù)據(jù)之前都會(huì)去主內(nèi)存中獲取數(shù)據(jù)(廚師炒菜之前都要去冰箱里拿食材)

  1. Thread:廚師
  2. 工作內(nèi)存:鐵鍋
  3. store&load:放熟食,取食材
  4. 主內(nèi)存:冰箱

讀者可思考以下情景:<br> 餐廳來了一位顧客點(diǎn)了一份紅燒肉,此時(shí)有兩位大廚(假設(shè)大廚之間互不通信),由于互不通信,所以兩位大廚都打開冰箱取出食材開始炒菜。 最后炒出了兩份紅燒肉,顧客只要一份。為什么會(huì)造成這種結(jié)果?

由于大廚之間沒有可見性。

將此情景放在JAVA中即是:<br> 線程A從主內(nèi)存中取了一個(gè)變量到工作內(nèi)存中,操作完畢后沒有及時(shí)放回主內(nèi)存中,于是線程B去取這個(gè)變量已經(jīng)過期了,取的是線程A操作之前的變量。

如何擁有可見性?

先介紹一下Java內(nèi)存模型中定義的8種工作內(nèi)存與主內(nèi)存之間的原子操作

  1. lock( 鎖定 ):作用于主內(nèi)存的變量,把一個(gè)變量標(biāo)識(shí)為一條線程獨(dú)占的狀態(tài)。
  2. unlock(解鎖):作用于主內(nèi)存的變量,把一個(gè)處于鎖定的變量釋放出來,釋放變量才可以被其他線程鎖定。
  3. read(讀?。鹤饔糜谥鲀?nèi)存的變量,把一個(gè)變量的值從主內(nèi)存?zhèn)鬏數(shù)骄€程的工作內(nèi)存中,以便隨后的load動(dòng)作使用。
  4. load(載入):作用于***工作內(nèi)存***的變量,它把read操作從主內(nèi)存中得到的變量值放入工作內(nèi)存的變量副本中。
  5. use(使用):作用于***工作內(nèi)***存種的變量,它把工作內(nèi)存中一個(gè)變量的值傳遞給執(zhí)行引擎,每當(dāng)虛擬機(jī)遇到一個(gè)需要使用到變量的值的字節(jié)碼指令時(shí)將會(huì)執(zhí)行這個(gè)操作。
  6. assign(賦值):作用于***工作內(nèi)存***中的變量,它把一個(gè)從執(zhí)行引擎接收到的值賦給工作內(nèi)存的變量,每當(dāng)虛擬機(jī)遇到一個(gè)給變量賦值的字節(jié)碼指令時(shí)執(zhí)行這個(gè)操作。
  7. store(存儲(chǔ)):作用于***工作內(nèi)存***的變量,它把工作內(nèi)存中一個(gè)變量的值傳送到主內(nèi)存中,以便隨后的write操作使用
  8. write(寫入):作用于主內(nèi)存的變量,它把store操作從工作內(nèi)存中得到的值放入主內(nèi)存的變量中。

讀取賦值一個(gè)普通變量的情況

發(fā)起read操作到write操作套流程的時(shí)間里,線程2隨時(shí)都有可能對(duì)這個(gè)主內(nèi)存對(duì)象發(fā)起第二套操作

有什么危害呢?
假設(shè)主內(nèi)存中有一個(gè)

int a=0;

線程1和線程2分別執(zhí)行一次,理想狀態(tài)下最終a的值為2.

a++;

線程1在執(zhí)行了assign操作之后變量a的真實(shí)值已經(jīng)從0變成了1,但是這個(gè)過程發(fā)生在工作內(nèi)存中對(duì)其他線程不可見,若線程2此時(shí)對(duì)變量a的操作,讀取到的值仍然為0,因?yàn)闆]有可見性,線程2的操作也僅僅是重復(fù)了線程1的操作,再次讓a從0變成了1。并沒有達(dá)到期望的a=2。

讀取賦值一個(gè)volatile變量的情況

操作更嚴(yán)格:

use之前不能被read&load
assign之后必須緊跟store&write
也就是說 read-load-use 和 assign-store-write成為了兩個(gè)不可分割的原子操作

盡管這時(shí)候在use和assign之間依然有一段真空期,有可能變量會(huì)被其他線程讀取,但是無論在哪一個(gè)時(shí)間點(diǎn)主內(nèi)存的變量和任一工作內(nèi)存的變量的值都是相等的。這個(gè)特性就導(dǎo)致了volatile變量不適合參與到依賴當(dāng)前值的運(yùn)算,如自增。 那么依靠可見性的特點(diǎn)volatile可以用在哪些地方呢? 《Java虛擬機(jī)》提到:

運(yùn)算結(jié)果并不依賴變量的當(dāng)前值(即結(jié)果對(duì)產(chǎn)生中間結(jié)果不依賴),或者能夠確保只有單一的線程修改變量的值
通常volatile用做保存某個(gè)狀態(tài)的boolean值。

以上所述是小編給大家介紹的Java并發(fā)編程-volatile可見性詳解整合,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • Jexcel實(shí)現(xiàn)按一定規(guī)則分割excel文件的方法

    Jexcel實(shí)現(xiàn)按一定規(guī)則分割excel文件的方法

    這篇文章主要介紹了Jexcel實(shí)現(xiàn)按一定規(guī)則分割excel文件的方法,涉及java操作Excel文件的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • SpringMVC方法返回值多種情況代碼實(shí)例

    SpringMVC方法返回值多種情況代碼實(shí)例

    這篇文章主要介紹了SpringMVC方法返回值多種情況代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • 基于JavaMail的常用類詳細(xì)介紹

    基于JavaMail的常用類詳細(xì)介紹

    以下是對(duì)JavaMail的常用類進(jìn)行了詳細(xì)分析的介紹,需要的朋友可以過來參考下
    2013-09-09
  • Java使用Freemarker頁面靜態(tài)化生成的實(shí)現(xiàn)

    Java使用Freemarker頁面靜態(tài)化生成的實(shí)現(xiàn)

    這篇文章主要介紹了Java使用Freemarker頁面靜態(tài)化生成的實(shí)現(xiàn),頁面靜態(tài)化是將原來的動(dòng)態(tài)網(wǎng)頁改為通過靜態(tài)化技術(shù)生成的靜態(tài)網(wǎng)頁,FreeMarker?是一個(gè)用?Java?語言編寫的模板引擎,它基于模板來生成文本輸,更多相關(guān)內(nèi)容需要的小伙伴可以參考一下
    2022-06-06
  • Java編程打印購物小票實(shí)現(xiàn)代碼

    Java編程打印購物小票實(shí)現(xiàn)代碼

    這篇文章主要介紹了Java編程打印購物小票實(shí)現(xiàn)代碼,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • 使用GSON庫將Java中的map鍵值對(duì)應(yīng)結(jié)構(gòu)對(duì)象轉(zhuǎn)換為JSON

    使用GSON庫將Java中的map鍵值對(duì)應(yīng)結(jié)構(gòu)對(duì)象轉(zhuǎn)換為JSON

    GSON是由Google開發(fā)并開源的實(shí)現(xiàn)Java對(duì)象與JSON之間相互轉(zhuǎn)換功能的類庫,這里我們來看一下使用GSON庫將Java中的map鍵值對(duì)應(yīng)結(jié)構(gòu)對(duì)象轉(zhuǎn)換為JSON的示例:
    2016-06-06
  • java異步編程的7種實(shí)現(xiàn)方式小結(jié)

    java異步編程的7種實(shí)現(xiàn)方式小結(jié)

    異步處理的實(shí)現(xiàn)方式有很多種,常見多線程,消息中間件,發(fā)布訂閱的廣播模式,本文就詳細(xì)的介紹java異步編程的7種實(shí)現(xiàn)方式,感興趣的可以了解一下
    2023-03-03
  • Java中jstat命令的使用詳解

    Java中jstat命令的使用詳解

    jstat命令可以查看堆內(nèi)存各部分的使用量,以及加載類的數(shù)量,下面這篇文章主要給大家介紹了關(guān)于Java中jstat命令使用的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-03-03
  • Java中的ScheduledThreadPoolExecutor定時(shí)任務(wù)詳解

    Java中的ScheduledThreadPoolExecutor定時(shí)任務(wù)詳解

    這篇文章主要介紹了Java中的ScheduledThreadPoolExecutor詳解,??ScheduledThreadPoolExecutor?繼承自?ThreadPoolExecutor,它主要用來在給定的延遲之后運(yùn)行任務(wù),或者定期執(zhí)行任務(wù),ScheduledThreadPoolExecutor?的功能與?Timer?類似<BR>,需要的朋友可以參考下
    2023-12-12
  • SpringBoot配置使Mybatis打印SQL執(zhí)行時(shí)的實(shí)際參數(shù)值操作

    SpringBoot配置使Mybatis打印SQL執(zhí)行時(shí)的實(shí)際參數(shù)值操作

    這篇文章主要介紹了SpringBoot配置使Mybatis打印SQL執(zhí)行時(shí)的實(shí)際參數(shù)值操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12

最新評(píng)論