溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java并發(fā)編程的基礎(chǔ)

發(fā)布時間:2021-08-25 18:37:02 來源:億速云 閱讀:107 作者:chen 欄目:大數(shù)據(jù)

這篇文章主要介紹“java并發(fā)編程的基礎(chǔ)”,在日常操作中,相信很多人在java并發(fā)編程的基礎(chǔ)問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”java并發(fā)編程的基礎(chǔ)”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

CPU多級緩存

為什么需要CPU緩存?

原因是,CPU的頻率太快了,快到主存跟不上,這樣在處理器時鐘周期內(nèi),CPU常常需要等待主存,浪費資源。所以cache的出現(xiàn),是為了緩解CPU和內(nèi)存之間速度的不匹配問題。

CPU緩存有什么意義?

  • 時間局部性:如果某個數(shù)據(jù)被訪問,那么在不久的將來它很有可能被再次訪問。

  • 空間局部性:如果某個數(shù)據(jù)被訪問,那么與它相鄰的數(shù)據(jù)很快也可能被訪問。

CPU多級緩存-緩存一致性(MESI)

用于保證多個CPU cache之間緩存共享數(shù)據(jù)的一致

CPU多級緩存-亂序執(zhí)行優(yōu)化

處理器為了提高執(zhí)行速度而做出的違背代碼原有順序的優(yōu)化。在單核情況下沒有問題,但是在多核環(huán)境下會出現(xiàn)問題。

JAVA內(nèi)存模型(Java Memory Model,JMM)

這是一種規(guī)范,規(guī)范了Java虛擬機與計算機內(nèi)存是如何協(xié)同工作的,規(guī)定了一個線程如何以及何時可以看到其他線程修改共享變量的值并且如何同步訪問共享變量。

java并發(fā)編程的基礎(chǔ)

如上圖所示,java內(nèi)存模型要求,調(diào)用棧和本地變量存放在線程棧上,如圖中Thread Stack,對象存放在堆中(Heap)。本地變量Local variable2是一個指向?qū)ο蟮囊?,Local variable存放在線程棧上,但對象存放在堆上。存放在堆上的對象可以被所持有對這個對象引用的線程訪問,并且可以訪問這個對象的成員變量,而當兩個線程同時訪問object3上的同一個方法時,都會訪問方法中的成員變量,那么每一個線程會擁有這個對象成員變量的私有拷貝。

java并發(fā)編程的基礎(chǔ)

線程之間的通信必須經(jīng)過主內(nèi)存,例如線程A想要與線程B進行通信,線程A需要將共享變量的副本刷新到主內(nèi)存中,然后線程B讀取主內(nèi)存的線程A更新過的共享變量。因此會出現(xiàn)同步問題。

同步往往有8種操作:

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

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

  • read(讀?。鹤饔糜谥鲀?nèi)存的變量,把一個變量值從主內(nèi)存?zhèn)鬏數(shù)骄€程的工作內(nèi)存中,以便隨后的load動作使用

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

  • use(使用):作用于工作內(nèi)存的變量,把工作內(nèi)存中的一個變量值傳遞給執(zhí)行引擎。

  • assign(賦值):作用于工作內(nèi)存的變量,它把一個執(zhí)行引擎接收到的值賦值給工作內(nèi)存的變量。

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

  • write(寫入):作用于主內(nèi)存的變量,它把store操作從工作內(nèi)存中一個變量的值傳送到主內(nèi)存的變量中。

同步規(guī)則:

  • 如果要把一個變量從主內(nèi)存中復制到工作內(nèi)存,就需要按順序的執(zhí)行read和load操作;如果把變量從工作內(nèi)存中同步回主內(nèi)存中,就要按順序地執(zhí)行store和write操作。但java內(nèi)存模型只要求上述操作必須按順序執(zhí)行,而沒有保證必須是連續(xù)執(zhí)行。

  • 不允許read和load、store和write操作之一單獨出現(xiàn)。

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

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

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

  • 一個變量在同一時刻只允許一條線程對其進行l(wèi)ock操作,但lock操作可以被同一條線程重復執(zhí)行多次,多次執(zhí)行l(wèi)ock后,只有執(zhí)行相同次數(shù)的unlock操作,變量才會被解鎖。lock和unlock必須成對出現(xiàn)。

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

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

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

java并發(fā)編程的基礎(chǔ) 

并發(fā)的優(yōu)勢與風險

優(yōu)勢:

  • 速度:同時處理多個請求,響應更快;復雜的操作可以分成多個進程同時進行。

  • 設(shè)計:程序設(shè)計在某些情況下更簡單,也可以有更多的選擇。

  • 資源利用:CPU能夠在等待IO的時候做一些其他的事情。

風險:

  • 安全性:多個線程共享數(shù)據(jù)時可能會產(chǎn)生與期望不相符的結(jié)果

  • 活躍性:某個操作無法繼續(xù)進行下去時,就會發(fā)生活躍性問題。比如死鎖、饑餓等問題。

  • 性能:線程過多會使得CPU頻繁切換,調(diào)度時間增多,同步機制,消耗過多內(nèi)存。

到此,關(guān)于“java并發(fā)編程的基礎(chǔ)”的學習就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI