国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

keithyau / 1169人閱讀

摘要:講什么內(nèi)存模型描述了多個(gè)線程之間通過(guò)內(nèi)存交互的規(guī)范,屏蔽了各種硬件和操作系統(tǒng)的訪問(wèn)差異的,保證了程序在各種平臺(tái)下對(duì)內(nèi)存的訪問(wèn)都能保證效果一致。這個(gè)版本的內(nèi)存模型在中仍然在使用。

JMM講什么

內(nèi)存模型(Memory Model)描述了多個(gè)線程之間通過(guò)內(nèi)存交互的規(guī)范,屏蔽了各種硬件和操作系統(tǒng)的訪問(wèn)差異的,保證了Java程序在各種平臺(tái)下對(duì)內(nèi)存的訪問(wèn)都能保證效果一致。在現(xiàn)代的多處理器(多核處理器)系統(tǒng)中,處理器擁有多級(jí)緩存以提升內(nèi)存訪問(wèn)速度同時(shí)減少了內(nèi)存總線的訪問(wèn)量。變量最終會(huì)保存在內(nèi)存中,但是編譯器、運(yùn)行時(shí)、處理器可以對(duì)指令優(yōu)化和重新排序,緩存、寄存器也對(duì)內(nèi)存進(jìn)行了讀寫優(yōu)化,只要保證在單個(gè)線程內(nèi)行為與代碼順序串行語(yǔ)義相同即可。內(nèi)存模型定義了充分且必要的條款,描述了程序中變量之間的關(guān)系,以及變量的讀取、寫入的底層細(xì)節(jié),實(shí)現(xiàn)了并發(fā)過(guò)程中的原子性、可見(jiàn)性、有序性。

老版本JMM中的問(wèn)題

原始的Java內(nèi)存模型存在一些不足,因此Java內(nèi)存模型在Java 1.5時(shí)被重新修訂(JSR133)。這個(gè)版本的Java內(nèi)存模型在Java 8中仍然在使用。老版本中的問(wèn)題有:

final字段的值并不是完全不變的。構(gòu)造器中對(duì)final字段值的寫入可以重排序至構(gòu)造函數(shù)返回并將對(duì)象引用賦值給變量之后,導(dǎo)致其它線程看到還未完成初始化的final字段。這個(gè)問(wèn)題的經(jīng)典案例是String的早期實(shí)現(xiàn)中,有多個(gè)final字段,但是其它線程可以看到字符串長(zhǎng)度為0,而實(shí)際上字符串長(zhǎng)度并不為0。

volatile字段的寫操作與非volatile字段的讀寫操作重排序。由于重排序的緣故,volatile字段的寫操作之前的操作被重新排序至之后進(jìn)行,導(dǎo)致其它線程看到的結(jié)果與程序代碼不一致。這個(gè)問(wèn)題的經(jīng)典案例是Double-Checked Locking(也稱multi-threaded singleton pattern)問(wèn)題,即通過(guò)一個(gè)volatile字段來(lái)判斷是否需要進(jìn)行初始化,從而實(shí)現(xiàn)延遲初始化并減少鎖操作的性能損耗。由于重排序的問(wèn)題,導(dǎo)致部分初始化操作或構(gòu)造操作被排序至volatile字段寫操作之后,導(dǎo)致其它線程看到部分初始化的數(shù)據(jù),破壞了數(shù)據(jù)的一致性。

JSR133解決的問(wèn)題

volatile語(yǔ)義增強(qiáng):volatile字段的讀、寫操作與其它任務(wù)內(nèi)存操作操作重排序,volatile的讀操作與監(jiān)視器鎖的獲取具有相同的內(nèi)存語(yǔ)義(緩存失效并從主存重新讀取),volatile的定操作與監(jiān)視器鎖的釋放具有相同的內(nèi)存語(yǔ)義(緩存刷入主存)。在這個(gè)約定下,線程A寫入volatile字段V后,線程B可以讀出V的值,同時(shí)線程A在寫入V時(shí)能夠看到的變量值對(duì)線程B也可見(jiàn)。

是否可以重排序 第二個(gè)操作 第二個(gè)操作 第二個(gè)操作
第一個(gè)操作 普通讀/普通寫 volatile讀/monitor enter volatile寫/monitor exit
普通讀/普通寫 No
voaltile讀/monitor enter No No No
volatile寫/monitor exit No No

其中普通讀指getfield, getstatic, 非volatile數(shù)組的arrayload, 普通寫指putfield, putstatic, 非volatile數(shù)組的arraystore。volatile讀寫分別是volatile字段的getfield, getstatic和putfield, putstatic。monitorenter是進(jìn)入同步塊或同步方法,monitorexist指退出同步塊或同步方法。

final字段增強(qiáng):只要對(duì)象正確構(gòu)造,那么不需要使用同步就可以保證任意線程都能看到final字段在構(gòu)造器中被初始化之后的值。編譯器會(huì)在final域的寫之后,構(gòu)造器函數(shù)return之前,插入StoreStore屏障。這個(gè)屏障禁止處理器把final域的寫重排序到構(gòu)造函數(shù)之外。寫final域的重排序規(guī)則可以保證:在對(duì)象引用為任意線程可見(jiàn)之前,對(duì)象的final域已經(jīng)被正確初始化過(guò)了,而普通域不具有這個(gè)保障。讀final域的重排序規(guī)則是,禁止處理器重排序初次讀取對(duì)象引用與初次讀取該對(duì)象包含的final域這兩個(gè)操作。編譯器會(huì)在讀final域操作的前面插入一個(gè)LoadLoad屏障。讀final域的重排序規(guī)則可以確保:在讀一個(gè)對(duì)象的final域之前,一定會(huì)先讀包含這個(gè)final域的對(duì)象的引用。

初次讀對(duì)象引用與初次讀該對(duì)象包含的final域,這兩個(gè)操作之間存在間接依賴關(guān)系。由于編譯器遵守間接依賴關(guān)系,因此不會(huì)重排序這兩個(gè)操作;大多數(shù)處理器也會(huì)遵守間接依賴,也不會(huì)重排序這兩個(gè)操作。但有少數(shù)處理器允許對(duì)存在間接依賴關(guān)系的操作做重排序(比如alpha處理器),這個(gè)規(guī)則就是專門用來(lái)針對(duì)這種處理器的。

對(duì)于引用類型,寫final域的重排序規(guī)則對(duì)編譯器和處理器增加了如下約束:

在構(gòu)造函數(shù)內(nèi)對(duì)一個(gè)final引用的對(duì)象的成員的寫入,與隨后在構(gòu)造函數(shù)外把這個(gè)被構(gòu)造對(duì)象的引用賦值給一個(gè)引用變量,這兩個(gè)操作之間不能重排序

確保在final引用的初始化在構(gòu)造函數(shù)內(nèi)完成,因此一旦其他線程拿到了一個(gè)非null的final引用,那么這個(gè)引用一定是在構(gòu)造函數(shù)內(nèi)被正確賦值的(至于是否正確初始化,則不一定,這取決于final引用的賦值語(yǔ)句)

Happens-Before規(guī)則

HappendBefore規(guī)則包括:

程序順序規(guī)則: 如果程序中操作A在操作B之前,那么同一個(gè)線程中操作A將在操作B之前進(jìn)行

監(jiān)視器鎖規(guī)則: 在監(jiān)視器鎖上的鎖操作必須在同一個(gè)監(jiān)視器鎖上的加鎖操作之前執(zhí)行

volatile變量規(guī)則: volatile變量的寫入操作必須在該變量的讀操作之前執(zhí)行

線程啟動(dòng)規(guī)則: 在線程上對(duì)Thread.start的調(diào)用必須在該線程中執(zhí)行任何操作之前執(zhí)行

線程結(jié)束規(guī)則: 線程中的任何操作都必須在其他線程檢測(cè)到該線程已經(jīng)結(jié)束之前執(zhí)行

中斷規(guī)則: 當(dāng)一個(gè)線程在另一個(gè)線程上調(diào)用interrupt時(shí),必須在被中斷線程檢測(cè)到interrupt之前執(zhí)行

傳遞性: 如果操作A在操作B之前執(zhí)行,并且操作B在操作C之前執(zhí)行,那么操作A在操作C之前執(zhí)行

相關(guān)鏈接

https://zhuanlan.zhihu.com/p/29881777

http://www.cs.umd.edu/~pugh/java/memoryModel/

https://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html

http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf

http://gee.cs.oswego.edu/dl/jmm/cookbook.html

https://liuzhengyang.github.io/2017/05/12/javamemorymodel/

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/73961.html

相關(guān)文章

  • 深入理解Java內(nèi)存模型(七)——總結(jié)

    摘要:編譯器,和處理器會(huì)共同確保單線程程序的執(zhí)行結(jié)果與該程序在順序一致性模型中的執(zhí)行結(jié)果相同。正確同步的多線程程序的執(zhí)行將具有順序一致性程序的執(zhí)行結(jié)果與該程序在順序一致性內(nèi)存模型中的執(zhí)行結(jié)果相同。 前情提要 深入理解Java內(nèi)存模型(六)——final 處理器內(nèi)存模型 順序一致性內(nèi)存模型是一個(gè)理論參考模型,JMM和處理器內(nèi)存模型在設(shè)計(jì)時(shí)通常會(huì)把順序一致性內(nèi)存模型作為參照。JMM和處理器內(nèi)...

    paney129 評(píng)論0 收藏0
  • 《深入理解 Java 內(nèi)存模型》讀書筆記

    摘要:前提深入理解內(nèi)存模型程曉明著,該書在以前看過(guò)一遍,現(xiàn)在學(xué)的東西越多,感覺(jué)那塊越重要,于是又再細(xì)看一遍,于是便有了下面的讀書筆記總結(jié)。同步同步是指程序用于控制不同線程之間操作發(fā)生相對(duì)順序的機(jī)制。線程之間的通信由內(nèi)存模型控制。 showImg(https://segmentfault.com/img/remote/1460000013474312?w=1920&h=1271); 前提 《深...

    xuexiangjys 評(píng)論0 收藏0
  • 《深入理解 Java 內(nèi)存模型》讀書筆記

    摘要:前提深入理解內(nèi)存模型程曉明著,該書在以前看過(guò)一遍,現(xiàn)在學(xué)的東西越多,感覺(jué)那塊越重要,于是又再細(xì)看一遍,于是便有了下面的讀書筆記總結(jié)。同步同步是指程序用于控制不同線程之間操作發(fā)生相對(duì)順序的機(jī)制。線程之間的通信由內(nèi)存模型控制。 showImg(https://mmbiz.qpic.cn/mmbiz_jpg/1flHOHZw6RtPu3BNx3zps1JhSmPICRw7QgeOmxOfTb...

    姘存按 評(píng)論0 收藏0
  • Java內(nèi)存模型

    摘要:內(nèi)存模型對(duì)內(nèi)存模型的介紹對(duì)內(nèi)存模型的結(jié)構(gòu)圖的線程之間的通信是通過(guò)共享內(nèi)存的方式進(jìn)行隱式通信,即線程把某狀態(tài)寫入主內(nèi)存中的共享變量,線程讀取的值,這樣就完成了通信。 Java內(nèi)存模型(JMM) 1.對(duì)內(nèi)存模型的介紹 ①對(duì)Java內(nèi)存模型的結(jié)構(gòu)圖 java的線程之間的通信是通過(guò)共享內(nèi)存的方式進(jìn)行隱式通信,即線程A把某狀態(tài)寫入主內(nèi)存中的共享變量X,線程B讀取X的值,這樣就完成了通信。是一種...

    sherlock221 評(píng)論0 收藏0
  • java內(nèi)存模型

    摘要:順序一致性內(nèi)存模型有兩大特性一個(gè)線程中所有操作必須按照程序的順序執(zhí)行。這里的同步包括對(duì)常用同步原語(yǔ)的正確使用通過(guò)以下程序說(shuō)明與順序一致性兩種內(nèi)存模型的對(duì)比順序一致性模型中所有操作完全按程序的順序串行執(zhí)行。 java內(nèi)存模型 java內(nèi)存模型基礎(chǔ) happen-before模型 JSR-133使用happen-before的概念來(lái)闡述操作之間的內(nèi)存可見(jiàn)性。在JMM中,如果一個(gè)操作執(zhí)行的結(jié)...

    2i18ns 評(píng)論0 收藏0
  • 深入理解Java內(nèi)存模型(三)——順序一致性

    摘要:下面是該程序在兩個(gè)內(nèi)存模型中的執(zhí)行時(shí)序?qū)Ρ葓D在順序一致性模型中,所有操作完全按程序的順序串行執(zhí)行。不保證未同步程序的執(zhí)行結(jié)果與該程序在順序一致性模型中的執(zhí)行結(jié)果一致。 前情提要 深入理解Java內(nèi)存模型(二)——重排序 數(shù)據(jù)競(jìng)爭(zhēng)與順序一致性保證 當(dāng)程序未正確同步時(shí),就會(huì)存在數(shù)據(jù)競(jìng)爭(zhēng)。java內(nèi)存模型規(guī)范對(duì)數(shù)據(jù)競(jìng)爭(zhēng)的定義如下: 在一個(gè)線程中寫一個(gè)變量, 在另一個(gè)線程讀同一個(gè)變量,...

    aristark 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<