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

Java內(nèi)存模型知識(shí)詳解

 更新時(shí)間:2020年07月31日 15:17:30   作者:殘雪余香  
這篇文章主要介紹了Java內(nèi)存模型知識(shí)詳解,文中通過(guò)對(duì)內(nèi)存訪問(wèn)時(shí)的交互關(guān)系圖解介紹的十分詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

1. 概述

  多任務(wù)和高并發(fā)是衡量一臺(tái)計(jì)算機(jī)處理器的能力重要指標(biāo)之一。一般衡量一個(gè)服務(wù)器性能的高低好壞,使用每秒事務(wù)處理數(shù)(Transactions Per Second,TPS)這個(gè)指標(biāo)比較能說(shuō)明問(wèn)題,它代表著一秒內(nèi)服務(wù)器平均能響應(yīng)的請(qǐng)求數(shù),而TPS值與程序的并發(fā)能力有著非常密切的關(guān)系。在討論Java內(nèi)存模型和線程之前,先簡(jiǎn)單介紹一下硬件的效率與一致性。

2.硬件的效率與一致性

  由于計(jì)算機(jī)的存儲(chǔ)設(shè)備與處理器的運(yùn)算能力之間有幾個(gè)數(shù)量級(jí)的差距,所以現(xiàn)代計(jì)算機(jī)系統(tǒng)都不得不加入一層讀寫速度盡可能接近處理器運(yùn)算速度的高速緩存(cache)來(lái)作為內(nèi)存與處理器之間的緩沖:將運(yùn)算需要使用到的數(shù)據(jù)復(fù)制到緩存中,讓運(yùn)算能快速進(jìn)行,當(dāng)運(yùn)算結(jié)束后再?gòu)木彺嫱交貎?nèi)存之中沒(méi)這樣處理器就無(wú)需等待緩慢的內(nèi)存讀寫了。
  基于高速緩存的存儲(chǔ)交互很好地解決了處理器與內(nèi)存的速度矛盾,但是引入了一個(gè)新的問(wèn)題:緩存一致性(Cache Coherence)。在多處理器系統(tǒng)中,每個(gè)處理器都有自己的高速緩存,而他們又共享同一主存,如下圖所示:多個(gè)處理器運(yùn)算任務(wù)都涉及同一塊主存,需要一種協(xié)議可以保障數(shù)據(jù)的一致性,這類協(xié)議有MSI、MESI、MOSI及Dragon Protocol等。Java虛擬機(jī)內(nèi)存模型中定義的內(nèi)存訪問(wèn)操作與硬件的緩存訪問(wèn)操作是具有可比性的,后續(xù)將介紹Java內(nèi)存模型。

  除此之外,為了使得處理器內(nèi)部的運(yùn)算單元能竟可能被充分利用,處理器可能會(huì)對(duì)輸入代碼進(jìn)行亂起執(zhí)行(Out-Of-Order Execution)優(yōu)化,處理器會(huì)在計(jì)算之后將對(duì)亂序執(zhí)行的代碼進(jìn)行結(jié)果重組,保證結(jié)果準(zhǔn)確性。與處理器的亂序執(zhí)行優(yōu)化類似,Java虛擬機(jī)的即時(shí)編譯器中也有類似的指令重排序(Instruction Recorder)優(yōu)化。

3.Java內(nèi)存模型

  定義Java內(nèi)存模型并不是一件容易的事情,這個(gè)模型必須定義得足夠嚴(yán)謹(jǐn),才能讓Java的并發(fā)操作不會(huì)產(chǎn)生歧義;但是,也必須得足夠?qū)捤桑沟锰摂M機(jī)的實(shí)現(xiàn)能有足夠的自由空間去利用硬件的各種特性(寄存器、高速緩存等)來(lái)獲取更好的執(zhí)行速度。經(jīng)過(guò)長(zhǎng)時(shí)間的驗(yàn)證和修補(bǔ),在JDK1.5發(fā)布后,Java內(nèi)存模型就已經(jīng)成熟和完善起來(lái)了。

3.1 主內(nèi)存與工作內(nèi)存

  Java內(nèi)存模型的主要目標(biāo)是定義程序中各個(gè)變量的訪問(wèn)規(guī)則,即在虛擬機(jī)中將變量存儲(chǔ)到內(nèi)存和從內(nèi)存中取出變量這樣底層細(xì)節(jié)。此處的變量與Java編程時(shí)所說(shuō)的變量不一樣,指包括了實(shí)例字段、靜態(tài)字段和構(gòu)成數(shù)組對(duì)象的元素,但是不包括局部變量與方法參數(shù),后者是線程私有的,不會(huì)被共享。

  Java內(nèi)存模型中規(guī)定了所有的變量都存儲(chǔ)在主內(nèi)存中,每條線程還有自己的工作內(nèi)存(可以與前面將的處理器的高速緩存類比),線程的工作內(nèi)存中保存了該線程使用到的變量到主內(nèi)存副本拷貝,線程對(duì)變量的所有操作(讀取、賦值)都必須在工作內(nèi)存中進(jìn)行,而不能直接讀寫主內(nèi)存中的變量。不同線程之間無(wú)法直接訪問(wèn)對(duì)方工作內(nèi)存中的變量,線程間變量值的傳遞均需要在主內(nèi)存來(lái)完成,線程、主內(nèi)存和工作內(nèi)存的交互關(guān)系如下圖所示,和上圖很類似。

這里的主內(nèi)存、工作內(nèi)存與Java內(nèi)存區(qū)域的Java堆、棧、方法區(qū)不是同一層次內(nèi)存劃分。

3.2 內(nèi)存間交互操作

  關(guān)于主內(nèi)存與工作內(nèi)存之間的具體交互協(xié)議,即一個(gè)變量如何從主內(nèi)存拷貝到工作內(nèi)存、如何從工作內(nèi)存同步到主內(nèi)存之間的實(shí)現(xiàn)細(xì)節(jié),Java內(nèi)存模型定義了以下八種操作來(lái)完成:

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

  如果要把一個(gè)變量從主內(nèi)存中復(fù)制到工作內(nèi)存,就需要按順尋地執(zhí)行read和load操作,如果把變量從工作內(nèi)存中同步回主內(nèi)存中,就要按順序地執(zhí)行store和write操作。Java內(nèi)存模型只要求上述操作必須按順序執(zhí)行,而沒(méi)有保證必須是連續(xù)執(zhí)行。也就是read和load之間,store和write之間是可以插入其他指令的,如對(duì)主內(nèi)存中的變量a、b進(jìn)行訪問(wèn)時(shí),可能的順序是read a,read b,load b, load a。Java內(nèi)存模型還規(guī)定了在執(zhí)行上述八種基本操作時(shí),必須滿足如下規(guī)則:

  • 不允許read和load、store和write操作之一單獨(dú)出現(xiàn)
  • 不允許一個(gè)線程丟棄它的最近assign的操作,即變量在工作內(nèi)存中改變了之后必須同步到主內(nèi)存中。
  • 不允許一個(gè)線程無(wú)原因地(沒(méi)有發(fā)生過(guò)任何assign操作)把數(shù)據(jù)從工作內(nèi)存同步回主內(nèi)存中。
  • 一個(gè)新的變量只能在主內(nèi)存中誕生,不允許在工作內(nèi)存中直接使用一個(gè)未被初始化(load或assign)的變量。即就是對(duì)一個(gè)變量實(shí)施use和store操作之前,必須先執(zhí)行過(guò)了assign和load操作。
  • 一個(gè)變量在同一時(shí)刻只允許一條線程對(duì)其進(jìn)行l(wèi)ock操作,lock和unlock必須成對(duì)出現(xiàn)
  • 如果對(duì)一個(gè)變量執(zhí)行l(wèi)ock操作,將會(huì)清空工作內(nèi)存中此變量的值,在執(zhí)行引擎使用這個(gè)變量前需要重新執(zhí)行l(wèi)oad或assign操作初始化變量的值
  • 如果一個(gè)變量事先沒(méi)有被lock操作鎖定,則不允許對(duì)它執(zhí)行unlock操作;也不允許去unlock一個(gè)被其他線程鎖定的變量。
  • 對(duì)一個(gè)變量執(zhí)行unlock操作之前,必須先把此變量同步到主內(nèi)存中(執(zhí)行store和write操作)。

3.3 重排序

  在執(zhí)行程序時(shí)為了提高性能,編譯器和處理器經(jīng)常會(huì)對(duì)指令進(jìn)行重排序。重排序分成三種類型:

編譯器優(yōu)化的重排序。編譯器在不改變單線程程序語(yǔ)義放入前提下,可以重新安排語(yǔ)句的執(zhí)行順序。指令級(jí)并行的重排序。現(xiàn)代處理器采用了指令級(jí)并行技術(shù)來(lái)將多條指令重疊執(zhí)行。如果不存在數(shù)據(jù)依賴性,處理器可以改變語(yǔ)句對(duì)應(yīng)機(jī)器指令的執(zhí)行順序。內(nèi)存系統(tǒng)的重排序。由于處理器使用緩存和讀寫緩沖區(qū),這使得加載和存儲(chǔ)操作看上去可能是在亂序執(zhí)行。

從Java源代碼到最終實(shí)際執(zhí)行的指令序列,會(huì)經(jīng)過(guò)下面三種重排序:

為了保證內(nèi)存的可見(jiàn)性,Java編譯器在生成指令序列的適當(dāng)位置會(huì)插入內(nèi)存屏障指令來(lái)禁止特定類型的處理器重排序。Java內(nèi)存模型把內(nèi)存屏障分為L(zhǎng)oadLoad、LoadStore、StoreLoad和StoreStore四種:

3.4 同步機(jī)制

介紹volatile、synchronized和final

3.5 原子性、可見(jiàn)性與有序性

介紹三個(gè)特性

到此這篇關(guān)于Java內(nèi)存模型知識(shí)詳解的文章就介紹到這了,更多相關(guān)Java內(nèi)存模型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot使用異步線程池實(shí)現(xiàn)生產(chǎn)環(huán)境批量數(shù)據(jù)推送

    SpringBoot使用異步線程池實(shí)現(xiàn)生產(chǎn)環(huán)境批量數(shù)據(jù)推送

    本文主要介紹了SpringBoot使用異步線程池實(shí)現(xiàn)生產(chǎn)環(huán)境批量數(shù)據(jù)推送,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-02-02
  • Eclipse開(kāi)發(fā)JavaWeb項(xiàng)目配置Tomcat的方法步驟

    Eclipse開(kāi)發(fā)JavaWeb項(xiàng)目配置Tomcat的方法步驟

    本文主要介紹了Eclipse開(kāi)發(fā)JavaWeb項(xiàng)目配置Tomcat的方法步驟,首先介紹eclipse開(kāi)發(fā)JavaWeb項(xiàng)目需要配置的相關(guān)環(huán)境,使用tomcat軟件在本地搭建服務(wù)器,然后再在eclipse環(huán)境下配置tomcat,感興趣的可以了解一下
    2021-08-08
  • Java爬蟲(chóng)框架之WebMagic實(shí)戰(zhàn)

    Java爬蟲(chóng)框架之WebMagic實(shí)戰(zhàn)

    這篇文章主要介紹了Java爬蟲(chóng)框架之WebMagic實(shí)戰(zhàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • java中redis增刪查以及清理緩存的案例

    java中redis增刪查以及清理緩存的案例

    這篇文章主要介紹了java中redis增刪查以及清理緩存的案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • 創(chuàng)建Maven項(xiàng)目和Spring IOC實(shí)例過(guò)程解析

    創(chuàng)建Maven項(xiàng)目和Spring IOC實(shí)例過(guò)程解析

    這篇文章主要介紹了創(chuàng)建Maven項(xiàng)目和Spring IOC實(shí)例過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Spring Boot事務(wù)配置詳解

    Spring Boot事務(wù)配置詳解

    這篇文章主要介紹了Spring Boot事務(wù)配置詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • Java并發(fā)編程之CountDownLatch原理詳解

    Java并發(fā)編程之CountDownLatch原理詳解

    這篇文章主要介紹了Java并發(fā)編程之CountDownLatch原理詳解,CountDownLatch類中使用了一個(gè)繼承自AQS的共享鎖Sync對(duì)象,構(gòu)造CountDownLatch對(duì)象時(shí)會(huì)將傳入的線程數(shù)值設(shè)為AQS的state值,需要的朋友可以參考下
    2023-12-12
  • 教你用JAVA寫文本編輯器(三)

    教你用JAVA寫文本編輯器(三)

    這篇文章主要給大家介紹了關(guān)于用JAVA寫文本編輯器的相關(guān)資料,本文主要實(shí)現(xiàn)的是一個(gè)點(diǎn)擊選擇文本格式的窗口,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-11-11
  • 關(guān)于SpringCloud?Ribbon替換輪詢算法問(wèn)題

    關(guān)于SpringCloud?Ribbon替換輪詢算法問(wèn)題

    Spring?Cloud?Ribbon是基于Netlix?Ribbon實(shí)現(xiàn)的一套客戶端負(fù)載均衡的工具。接下來(lái)通過(guò)本文給大家介紹SpringCloud?Ribbon替換輪詢算法問(wèn)題,需要的朋友可以參考下
    2022-01-01
  • Spring batch批處理框架

    Spring batch批處理框架

    本文主要介紹了Spring batch批處理框架的相關(guān)知識(shí)。具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-04-04

最新評(píng)論

宜兴市| 秭归县| 慈利县| 安仁县| 怀柔区| 明光市| 五家渠市| 京山县| 禄丰县| 外汇| 太康县| 望谟县| 肥城市| 九寨沟县| 乡城县| 新沂市| 安徽省| 和田市| 司法| 调兵山市| 平阴县| 德州市| 天门市| 通海县| 稷山县| 肥城市| 禹城市| 乐陵市| 铁力市| 新竹县| 平顺县| 哈巴河县| 体育| 土默特左旗| 三河市| 榆社县| 西乌珠穆沁旗| 辽阳县| 黔西| 叶城县| 珲春市|