JMM(JAVA內存模型)

JMM是啥

JMM是一個抽象的概念,描述的是一種規範,定義了各個程序中變量的訪問方式。 JMM規定,全部變量都存儲在主內存中,主內存是共享區域,全部線程均可以訪問,可是線程對變量的操做必須在工做內存中進行。安全

基本類型數據會直接存儲在工做內存中 引用內存會存儲在主內存中多線程

重排序

編譯器爲了最佳的執行效率會對代碼進行重編譯,編譯不會改變原程序的執行結果(單線程中)併發

JMM模型特徵

原子性app

可見性線程

有序性翻譯

引發的問題

在多線程中就會形成併發問題對象

如何解決

JMM提供了8種原子操做排序

lock 鎖定事件

unlock 解鎖內存

read 讀取

load 載入

use 使用

assign 賦值

store 存儲

write 寫入

JMM對這八種指令的使用,制定了以下規則:

不容許read和load、store和write操做之一單獨出現。即便用了read必須load,使用了store必須write

不容許線程丟棄他最近的assign操做,即工做變量的數據改變了以後,必須告知主存

不容許一個線程將沒有assign的數據從工做內存同步回主內存

一個新的變量必須在主內存中誕生,不容許工做內存直接使用一個未被初始化的變量。就是懟變量實施use、store操做以前,必須通過assign和load操做

一個變量同一時間只有一個線程能對其進行lock。屢次lock後,必須執行相同次數的unlock才能解鎖

若是對一個變量進行lock操做,會清空全部工做內存中此變量的值,在執行引擎使用這個變量前,必須從新load或assign操做初始化變量的值

若是一個變量沒有被lock,就不能對其進行unlock操做。也不能unlock一個被其餘線程鎖住的變量

對一個變量進行unlock操做以前,必須把此變量同步回主內存

對基本數據類型讀寫操做的原子性

Happen-Before(先行發生規則)

  在常規的開發中,若是咱們經過上述規則來分析一個併發程序是否安全,估計腦袋會很疼。由於更多時候,咱們是分析一個併發程序是否安全,其實都依賴Happen-Before原則進行分析。   Happen-Before被翻譯成先行發生原則,意思就是當A操做先行發生於B操做,則在發生B操做的時候,操做A產生的影響能被B觀察到,「影響」包括修改了內存中的共享變量的值、發送了消息、調用了方法等。

  Happen-Before的規則有如下幾條

程序次序規則(Program Order Rule):在一個線程內,程序的執行規則跟程序的書寫規則是一致的,從上往下執行。

管程鎖定規則(Monitor Lock Rule):一個Unlock的操做確定先於下一次Lock的操做。這裏必須是同一個鎖。同理咱們能夠認爲在synchronized同步同一個鎖的時候,鎖內先行執行的代碼,對後續同步該鎖的線程來講是徹底可見的。

volatile變量規則(volatile Variable Rule):對同一個volatile的變量,先行發生的寫操做,確定早於後續發生的讀操做

線程啓動規則(Thread Start Rule):Thread對象的start()方法先行發生於此線程的每個動做

線程停止規則(Thread Termination Rule):Thread對象的停止檢測(如:Thread.join(),Thread.isAlive()等)操做,必行晚於線程中全部操做

線程中斷規則(Thread Interruption Rule):對線程的interruption()調用,先於被調用的線程檢測中斷事件(Thread.interrupted())的發生

對象停止規則(Finalizer Rule):一個對象的初始化方法先於一個方法執行Finalizer()方法

傳遞性(Transitivity):若是操做A先於操做B、操做B先於操做C,則操做A先於操做C

相關文章
相關標籤/搜索