Java 內(nèi)存模型與線程

概述:

1.每個電腦的處理器(CPU)都有自己的高速緩存以達(dá)到讀寫速度提高,但多個高速緩存共享同一塊主內(nèi)存,當(dāng)多個處理器的運(yùn)算任務(wù)涉及到主內(nèi)存中的同一塊數(shù)據(jù),就有可能發(fā)生各自的數(shù)據(jù)不一致,針對這種情況,需要有一定的協(xié)議來解決數(shù)據(jù)一致性的問題。
2.JAVA虛擬機(jī)中通過實(shí)現(xiàn)自己的‘內(nèi)存模型’對高速緩存和內(nèi)存的讀寫的過程抽象。
3.為了讓處理器中的運(yùn)算單元被充分利用,處理器可能對輸入的代碼進(jìn)行亂序折行優(yōu)化,然后再進(jìn)行重組,所以計(jì)算的的結(jié)果不能依靠代碼中的順序,在JAVA虛擬機(jī)中,對應(yīng)的為 指令重排。

image.png

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

1.java內(nèi)存模型是為了定義程序中各個變量的訪問規(guī)則,即變量存儲到主內(nèi)存和從主內(nèi)存中取出的操作。(該變量不包括局部變量,因?yàn)槠鋵?shí)線程私有的,不會共享)
2.所有變量(實(shí)例,靜態(tài)字段,數(shù)組等)都存儲在主內(nèi)存,每條線程都有贊成的工作內(nèi)存(高速緩存),工作內(nèi)存中保存的變量是該變量從主內(nèi)存的拷貝,線程對變量的所有操作都必須在工作內(nèi)存里面,不允許直接操作主內(nèi)存,不同的線程無法互相訪問工作內(nèi)存中的變量,必須通過訪問主內(nèi)存的變量
ps:volitate變量依然有拷貝

JAVA虛擬機(jī)中定義了8種操作,將一個變量正確地從主內(nèi)存拷貝到工作內(nèi)存,或者從工作內(nèi)存同步到主內(nèi)存。

  • lock:
  • unlock:
  • read:
  • load :
  • use :
  • assign:
  • store:
  • write:
    JAVA內(nèi)存模型要求上面的操作是順序性的,但是沒有保證是要連續(xù)性,

volatile關(guān)鍵字

  • 當(dāng)一個變量被volatile關(guān)鍵字修飾的時候,具備兩種特性:1.此變量對所有線程是可見的。2,禁止指令重排。
  • volatile變量每次使用之前,都會進(jìn)行一次刷新。
    -只能保證可見性。

不符合以下2中情況下volatile變量還是非線程安全的:

  • 1.運(yùn)算結(jié)果不依賴于當(dāng)前的值,或者確保只有單一的線程修改變量的值,其他線程只是讀取,
  • 2.變量不需要跟其他狀態(tài)的變量共同參與不變約束。

原子性:

JAVA中提供了synchronized關(guān)鍵字,在synchronized塊之間的操作是具備原子性的。

可見性:

  • 可見性是指當(dāng)一個線程修改了共享的值時,其他線程能夠立即得知這個修改,其中volatile變量的特殊規(guī)則保證了新值(被修改的變量)內(nèi)夠立即同步到主內(nèi)存。
  • 還有synchronized和final關(guān)鍵字內(nèi)夠保證可見性,

有序性:

  • volatile:禁止指令重排
  • synchronized: 一個變量在同一個時刻只允許一條線程對其進(jìn)行l(wèi)ock,也就是說持有同一個鎖的兩個同步塊只能穿行地進(jìn)入。

線程相關(guān):

實(shí)現(xiàn)線程有3種方式:內(nèi)核線程,用戶線程,用戶加輕量級進(jìn)程

  • 1.內(nèi)核線程有操作系統(tǒng)直接支持,有內(nèi)核完成線程的調(diào)度切換。
  • 2.非內(nèi)核線程的線程。其建立,同步和銷魂都是在用戶態(tài)完成,不用切換到內(nèi)核態(tài),所以速度快。
  • 3.JAVA線程是基于用戶線程去實(shí)現(xiàn)的,其調(diào)度方式是搶占式線程調(diào)度(另外一種是協(xié)同式),每個線程由系統(tǒng)分配時間,切換不用本身決定,線程執(zhí)行時間可控。雖然可以通過設(shè)置優(yōu)先級讓線程獲取多點(diǎn)的系統(tǒng)時間,但是最終的調(diào)度還是有系統(tǒng)決定。

狀態(tài):
1.new.
2.運(yùn)行runnale:
3.無限期等待:這種情況不會分配cpu時間,實(shí)現(xiàn)方式有:Object.wait(),thread.join.
4.限期等待:這種情況不會分配cpu時間。實(shí)現(xiàn)方式有:
Object.wait(times), Thread.join(time),Thread.sleep(time)
5.阻塞(blocked):等待獲取一個排他鎖。
6.結(jié)束。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容