日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

JVM-并发-Java 内存模型

發(fā)布時間:2023/12/9 java 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JVM-并发-Java 内存模型 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?Java內(nèi)存模型

    (1). 主內(nèi)存與工作內(nèi)存

      Java內(nèi)存模型規(guī)定了所有的變量都存儲在主內(nèi)存中.

      每類線程的變量的主內(nèi)存副本拷貝,線程對變量的所有操作(讀操作,賦值操作等)都必須工作內(nèi)存中進行,而不能直接讀寫主內(nèi)存中的變量.

      不同的線程之間無法直接訪問對方工作內(nèi)存中的變量,線程間變量的傳遞均需要通過主內(nèi)存來完成.

    (2)內(nèi)存之間額操作

      主內(nèi)存與工作內(nèi)存交互,Java內(nèi)存模型定義了8種操作來完成.

      a)lock(鎖定):作用于主內(nèi)存的變量,它把一個變量標識為一條線性獨占的狀態(tài).

      b)ublock(解鎖):作用于主內(nèi)存的變量,它把一個處于鎖狀態(tài)的變量釋放出來,釋放后的變量才可以被其他線程鎖定.

      c)read(讀取):作用于主內(nèi)存的變量,它把一個變量的值從主內(nèi)存?zhèn)鬏數(shù)骄€程的內(nèi)存中,以便隨后的load動作使用.

      d)load(載入):作用于內(nèi)存的變量,它把read操作從主內(nèi)存中得到的變量值放入工作內(nèi)存的變量副本中.

      e)use(使用):作用于工作內(nèi)存中的變量,它把工作內(nèi)存中的一個變量的值傳遞給執(zhí)行引擎,每當虛擬機遇到一個需要使用變量的值的字節(jié)碼指令時將會執(zhí)行這個操作.

      f)assign(賦值):作用于工作內(nèi)存中的變量,它把一個執(zhí)行引擎接收到的值賦值給工作內(nèi)存的變量,每當虛擬機遇到一個給變量賦值的字節(jié)碼指令時執(zhí)行這個操作.

      g)store(存儲):作用于工作內(nèi)存的變量,它把工作內(nèi)存中一個變量的值傳遞到主內(nèi)存中,以便隨后的write操作使用.

      h)write(寫入):作用于主內(nèi)存的變量,它把store操作從工作內(nèi)存中得到的變量的值放入到主內(nèi)存的變量中.

?    (3)Java內(nèi)存模型規(guī)定了在執(zhí)行上述8種基本操作時必須滿足如下規(guī)則:

      a) 不允許read和load,store和write操作之一單獨出現(xiàn),既不允許一個變量從主存讀取了但是工作內(nèi)存發(fā)起回寫不接受的情況出現(xiàn)

      b) 不允許一個線程丟棄它的最近的assign操作,即變量在工作內(nèi)存中改變了之后必須把變量同步到主內(nèi)存

      c) 不允許一個線程無原因(沒有發(fā)生過任何assign操作)把數(shù)據(jù)從線程的工作內(nèi)存同步會主內(nèi)存

      d) 一個新的變量只能在主內(nèi)存中“誕生”,不允許在工作內(nèi)存中直接使用一個未被初始化的變量,換句話說就是 對一個變量實施use,store操作之前,必須執(zhí)行過了assign和load操作

      e) 一個人變量在同一時刻只允許一條線程對其進行l(wèi)ock操作可以被同一條線程重復(fù)執(zhí)行多次,多次執(zhí)行l(wèi)ock后,只有執(zhí)行相同德爾unlock操作,變量才會被解鎖

      f) 如果一個變量執(zhí)行l(wèi)ock操作,那將會清空工作內(nèi)存中此變量的值,在執(zhí)行引擎使用這個變量前,需要重新執(zhí)行l(wèi)oad或assign操作初始化變量的值

      g) 如果一個變量事先沒有被lock操作鎖定,那就不允許對它執(zhí)行unlock操作,也不允許unlock一個被其他線程鎖定的變量

      h) 對一個變量執(zhí)行unlock操作之前,必須先把此變量同步會煮主內(nèi)存(執(zhí)行store,write操作)

    (4)對于volatile型變量的特殊規(guī)則:
      a) 只能保證可見性

      b) 禁止指令重排序優(yōu)化

    (5)對long和double型變量的特殊規(guī)則:

      a) Java內(nèi)存模型規(guī)定:允許虛擬機將沒有被volatile修飾的64位數(shù)據(jù)的讀寫操作劃分為兩次32位操作進行,及允許虛擬機實現(xiàn)選擇可以不保證64位數(shù)據(jù)類型的load,store,read和write這4個操作的原子性。這就是long和double的非原子性協(xié)定

    (6)原子性、可見性與有序性

      原子性:由Java內(nèi)存模型來直接保證的原子性變量操作包括read,load,assign,use,store和write

      可見性:指當一個線程修改了共享變量的值,其他線程能夠立即得知這個修改

      有序性:如果在本線程內(nèi)觀察,所有的操作都是有序的,如果在一個線程中觀察另一個線程,所有的操作都是無序的

    (7)先行發(fā)生原則

      先行發(fā)生時Java內(nèi)存模型中定義的兩項操作之間的關(guān)系,如果說操作A先行發(fā)生于操作B,其實就是在發(fā)生操作B之前,操作A產(chǎn)生的影響能夠被操作B觀察到。“影響”包括修改了內(nèi)存中共享變量的值,發(fā)送了消息,調(diào)用了方法等。

      程序次序規(guī)則:在一個線程內(nèi),按照程序代碼順序,書寫在前面的操作先于發(fā)生在書寫在后面的操作。準確的說,應(yīng)該是控制流順序而不是程序代碼順序,因為要考慮分支、循環(huán)等結(jié)構(gòu)。

      管程鎖定規(guī)則:一個unlock操作先行發(fā)生于后面對同一個鎖的lock操作。

      volatile變量規(guī)則:對一個volatile變量的寫操作先行發(fā)生于后面對這個變量的讀操作,這里的“后面”是指時間上的先后順序

      線程啟動規(guī)則:Thread對象的start方法先行發(fā)生于此線程的每一個動作

      線程終止規(guī)則:線程中的所有操作都先于此線程的終止檢測,我們可以通過Thread.join()方法結(jié)束。THread.Alive()的返回值等手段檢到線程已經(jīng)終止執(zhí)行

      線程中斷規(guī)則:對線程interrupt()方法的調(diào)用先行發(fā)生于被中斷線程的代碼檢測到中斷事件的發(fā)生,可以通過Thread.interrupted()方法檢測到是否有中斷發(fā)生

      對象終結(jié)規(guī)則:一個對象的初始化完成(構(gòu)造函數(shù)執(zhí)行結(jié)束)先行發(fā)生于它的finalize()方法的開始

      傳遞性:如果操作A先行發(fā)生于操作B,操作B先行發(fā)生于操作C,那就得出操作A先行發(fā)生于操作C的結(jié)論

轉(zhuǎn)載于:https://www.cnblogs.com/lrh-xl/p/5364349.html

總結(jié)

以上是生活随笔為你收集整理的JVM-并发-Java 内存模型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。