自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

JMM理解

開發(fā) 前端
JMM(Java內(nèi)存模型Java Memory Model,簡稱JMM)本身是一種抽象的概念JMM(Java內(nèi)存模型Java Memory Model,簡稱JMM)本身是一種抽象的概念并不真實(shí)存在,它描述的一組規(guī)則或規(guī)范,通過這組規(guī)范定義了程序中各個(gè)變量(包括實(shí)例字段、靜態(tài)字段何構(gòu)成數(shù)組對(duì)象的元素)的訪問方式。

[[345560]]

JMM概念
JMM(Java內(nèi)存模型Java Memory Model,簡稱JMM)本身是一種抽象的概念JMM(Java內(nèi)存模型Java Memory Model,簡稱JMM)本身是一種抽象的概念并不真實(shí)存在,它描述的一組規(guī)則或規(guī)范,通過這組規(guī)范定義了程序中各個(gè)變量(包括實(shí)例字段、靜態(tài)字段何構(gòu)成數(shù)組對(duì)象的元素)的訪問方式。

并不真實(shí)存在,它描述的一組規(guī)則或規(guī)范,通過這組規(guī)范定義了程序中各個(gè)變量(包括實(shí)例字段、靜態(tài)字段何構(gòu)成數(shù)組對(duì)象的元素)的訪問方式。

JMM關(guān)于同步的規(guī)定:

1、線程解鎖前,必須把共享變量的值刷新回主內(nèi)存

2、線程加鎖前,必須讀取主內(nèi)存的最新值到自己的工作內(nèi)存

3、加鎖解鎖是同一把鎖

由于JVM運(yùn)行程序的實(shí)體是線程,而每個(gè)線程創(chuàng)建時(shí)JVM都會(huì)為其創(chuàng)建一個(gè)工作內(nèi)存(有些地方稱為??臻g),工作內(nèi)存是每個(gè)線程的私有數(shù)據(jù)區(qū)域,而Java內(nèi)存模型中的規(guī)定所有變量都存儲(chǔ)在主內(nèi)存,主內(nèi)存是共享內(nèi)存區(qū)域,所有線程都可以訪問,但線程對(duì)變量的操作(讀取賦值等)必須在工作內(nèi)存中進(jìn)行,首先要將變量從主內(nèi)存拷貝到線程自己的工作內(nèi)存空間,然后對(duì)變量進(jìn)行操作,操作完成后再將變量寫會(huì)主內(nèi)存,不能直接操作主內(nèi)存中的變量,各個(gè)線程中的工作內(nèi)存中存儲(chǔ)著主內(nèi)存中的變量副本拷貝,因此不同的線程間無法訪問對(duì)方的工作內(nèi)存,線程間的通信(傳值)必須通過主內(nèi)存來完成,其簡要訪問過程入下圖:

JMM理解

JMM 的八種內(nèi)存交互操作
為了更直觀,先來看看這張圖吧:

  1. lock(鎖定):作用于主內(nèi)存中的變量,一個(gè)變量在同一時(shí)間只能被一個(gè)線程鎖定,即把變量標(biāo)識(shí)為線程獨(dú)占狀態(tài)。
  2. read(讀取):作用于主內(nèi)存變量,表示把一個(gè)變量值從主內(nèi)存?zhèn)鬏數(shù)骄€程的工作內(nèi)存中,以便下一步的 load 操作使用。
  3. load(載入):作用于線程的工作內(nèi)存的變量,表示把 read 操作從主內(nèi)存中讀取的變量值放到工作內(nèi)存的變量副本中(副本是相對(duì)于主內(nèi)存的變量而言的)。
  4. use(使用):作用于線程的工作內(nèi)存中的變量,表示把工作內(nèi)存中的一個(gè)變量值傳遞給執(zhí)行引擎,每當(dāng)虛擬機(jī)遇到一個(gè)需要使用變量的值的字節(jié)碼指令時(shí)就會(huì)執(zhí)行該操作。
  5. assign(賦值):作用于線程的工作內(nèi)存的變量,表示把執(zhí)行引擎返回的值賦值給工作內(nèi)存中的變量,每當(dāng)虛擬機(jī)遇到一個(gè)給變量賦值的字節(jié)碼指令時(shí)就會(huì)執(zhí)行該操作。
  6. store(存儲(chǔ)):作用于線程的工作內(nèi)存中的變量,把工作內(nèi)存中的一個(gè)變量的值傳遞給主內(nèi)存,以便下一步的 write 操作使用。
  7. write(寫入):作用于主內(nèi)存的變量,表示把 store 操作從工作內(nèi)存中得到的變量的值放入主內(nèi)存的變量中。
  8. unlock(解鎖):作用于主內(nèi)存的變量,表示把一個(gè)處于鎖定狀態(tài)的變量釋放出來,釋放后的變量才可以被其他線程鎖定。

JMM 還規(guī)定了以上八種操作需按照如下規(guī)則進(jìn)行:

  • 不允許read 和 load、store 和 write 操作之一單獨(dú)出現(xiàn),也就是 read 操作后必須 load,store 操作后必須 write。即不允許一個(gè)變量從主內(nèi)存讀取了但工作內(nèi)存不接受,或者從工作內(nèi)存發(fā)起回寫了但主內(nèi)存不接受的情況出現(xiàn)。
  • 不允許線程丟棄它最近的 assign 操作,即變量在工作內(nèi)存中改變了之后必須把該變化同步回主內(nèi)存。
  • 不允許線程將沒有 assign 的數(shù)據(jù)從工作內(nèi)存同步到主內(nèi)存。
  • 一個(gè)新的變量必須在主內(nèi)存中誕生,不允許工作內(nèi)存直接使用一個(gè)未被初始化的變量。也就是對(duì)變量實(shí)施 use 和 store 操作之前,必須經(jīng)過 load 和 assign 操作。
  • 一個(gè)變量同一時(shí)間只能有一個(gè)線程對(duì)其進(jìn)行 lock 操作。但 lock 操作可以被同一條線程重復(fù)執(zhí)行多次,多次 lock 之后,必須執(zhí)行相同次數(shù) unlock 才可以解鎖。
  • 如果對(duì)一個(gè)變量進(jìn)行 lock 操作,會(huì)清空所有工作內(nèi)存中此變量的值。在執(zhí)行引擎使用這個(gè)變量前,必須重新 load 或 assign 操作初始化變量的值。
  • 如果一個(gè)變量沒有被 lock,就不能對(duì)其進(jìn)行 unlock 操作。也不能 unlock 一個(gè)被其他線程鎖住的變量。
  • 一個(gè)線程對(duì)一個(gè)變量進(jìn)行 unlock 操作之前,必須先把此變量同步回主內(nèi)存。

JMM 三大特征
JMM 三大特征分別是:原子性,可見性,有序性。整個(gè) JMM 實(shí)際上也是圍繞著這三個(gè)特征建立起來的,并且也是 Java 并發(fā)編程的基礎(chǔ)。

原子性

原子性是指一個(gè)操作是不可分割、不可中斷的,要么全部執(zhí)行成功要么全部執(zhí)行失敗。

JMM 只能保證對(duì)基本數(shù)據(jù)類型的變量的讀寫操作是原子性的,但 long 和 double 除外(long 和 double 的非原子性協(xié)定)。

我們來看看下面的例子:

int x = 1;

int y = x;

x ++;

上面三行代碼只有第一行是原子性操作,基本類型賦值操作,必定是原子性操作。

第二行代碼先讀取 x 變量的值,再進(jìn)行賦值給 y 變量,進(jìn)行了兩個(gè)操作,不能保證原子性。

第三行代碼先讀取 x 變量的值,再進(jìn)行加 1,最后再賦值給 x 變量,進(jìn)行了三個(gè)操作,不能保證原子性。

在并發(fā)環(huán)境下,為了保證原子性,Java 提供了 synchronized 關(guān)鍵字。因此在 synchronized 修飾的代碼塊之間的操作都是原子性的。

可見性

可見性是指所有線程都能看到共享內(nèi)存的最新狀態(tài)。即當(dāng)一個(gè)線程修改了一個(gè)共享變量的值時(shí),其他線程能夠立即看到該變量的最新值。

對(duì)于可見性問題,Java 是提供了一個(gè) volatile 關(guān)鍵字來保證可見性。當(dāng)一個(gè)共享變量被 volatile 關(guān)鍵字修飾時(shí),這個(gè)變量被修改后會(huì)立即刷新到主內(nèi)存,保證其他線程看到的值一定是最新的。

除了 volatile 關(guān)鍵字之外,final 和 synchronized 也能實(shí)現(xiàn)可見性。

final 關(guān)鍵字修飾的變量,在構(gòu)造器中一旦初始化完成,如果沒有對(duì)象逸出(指對(duì)象沒有初始化完成就可以被別的線程使用),那么其他線程都就可以看見 final 修飾的變量。

synchronized 的原理是,線程進(jìn)入 synchronized 代碼塊后,線程會(huì)獲取到 lock,將會(huì)清空本地內(nèi)存,然后從主內(nèi)存中拷貝共享變量的最新值到本地內(nèi)存作為副本,執(zhí)行代碼,又將修改后的副本值刷新到主內(nèi)存中,最后線程執(zhí)行 unlock。

有序性

有序性是指程序執(zhí)行的順序按照代碼的先后順序執(zhí)行。

在 Java 中,可以通過 volatile 和 synchronized 關(guān)鍵字來保證多線程之間操作的有序性。

volatile 關(guān)鍵字是通過在主存中加入內(nèi)存屏障來達(dá)到禁止指令重排序,來保證有序性。

synchronized 關(guān)鍵字原理是,一個(gè)變量在同一時(shí)刻只能被一個(gè)線程 lock,并且必須 unlock 后,其他線程才可以重新 lock,使得被 synchronized 修飾的代碼塊在多線程之間是串行執(zhí)行的。

【編輯推薦】

                                                                                                                                                                                                【責(zé)任編輯:姜華 TEL:(010)68476606】

 

 

責(zé)任編輯:姜華 來源: 今日頭條
相關(guān)推薦

2020-11-11 08:45:48

Java

2024-01-09 08:24:47

JMM核心線程

2021-05-09 18:32:05

JMMHappens-befJava

2021-05-17 08:18:35

Java內(nèi)存模型JMM

2020-06-09 08:11:33

MESI協(xié)議MM

2020-07-17 20:15:03

架構(gòu)JMMvolatile

2020-11-02 08:54:29

JMMVolatileSynchronize

2024-03-15 08:23:26

異步編程函數(shù)

2016-12-19 15:09:02

Jedis源碼

2017-03-06 16:56:37

深度學(xué)習(xí)本質(zhì)現(xiàn)狀

2023-09-25 08:20:15

分布式流處理平臺(tái)

2020-11-12 10:53:36

volatile

2024-11-18 16:37:35

JMMJava內(nèi)存模型

2024-01-10 08:03:25

JMM重排序處理器

2019-12-26 09:15:44

網(wǎng)絡(luò)IOLinux

2022-05-03 00:03:11

狀態(tài)管理前端開發(fā)

2024-10-12 10:29:11

計(jì)算機(jī)圖形

2018-02-26 12:55:00

2009-09-23 14:23:51

Hibernate主鍵

2012-05-08 10:14:45

設(shè)計(jì)原則
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)