欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

帶你快速搞定java多線程(4)

 更新時間:2021年07月14日 17:01:33   作者:香菜聊游戲  
這篇文章主要介紹了java多線程編程實例,分享了幾則多線程的實例代碼,具有一定參考價值,加深多線程編程的理解還是很有幫助的,需要的朋友可以參考下

1、AQS 是什么?

AQS 是類 AbstractQueuedSynchronizer的簡稱,也是常用鎖的基類,比如常見的ReentrantLock,Semaphore,CountDownLatch 等等。

AQS提供了一種實現(xiàn)阻塞鎖和一系列依賴FIFO等待隊列的同步器的框架。是Java提供的一種模板,一般在現(xiàn)有同步器無法完成的時候可以自行擴展。當(dāng)然也可以自己實現(xiàn),不過既然有現(xiàn)成的為什么還要自己瞎雞兒寫。

圖片

2、AQS 模型

圖片

注意:圖來自網(wǎng)上,具體的原地點在哪我也不知道。如果有問題可以聯(lián)系我。

解釋:整個模型相當(dāng)于在食堂吃飯,只開了一個窗口,只有一個打飯的師傅(state),所有想要吃飯的線程必須排隊等待,直到輪到自己。

AQS就是基于隊列,用共享變量state,線程通過CAS去改變狀態(tài)符,成功則獲取鎖成功,失敗則進(jìn)入等待隊列,等待被喚醒。代碼解決現(xiàn)實問題,現(xiàn)實問題催生解決方案。

3、AQS state

state 代表 共享資源和一個FIFO線程等待隊列(多線程爭用資源被阻塞時會進(jìn)入此隊列)。

state的訪問方式有三種:

  • getState()
  • setState()
  • compareAndSetState()

4、AQS 兩種資源共享方式:

1.Exclusive:獨占,只有一個線程能執(zhí)行,如ReentrantLock

2.Share:共享,多個線程可以同時執(zhí)行,如Semaphore、CountDownLatch、ReadWriteLock,CyclicBarrier。

5、模板方式實現(xiàn)自定義

不同的自定義同步器爭用共享資源的方式也不同。自定義同步器在實現(xiàn)時只需要實現(xiàn)共享資源state的獲取與釋放方式即可,至于具體線程等待隊列的維護(hù)(如獲取資源失敗入隊/喚醒出隊等),AQS已經(jīng)在頂層實現(xiàn)好了。自定義時主要實現(xiàn)以下幾種方法:

  • isHeldExclusively():該線程是否正在獨占資源。只有用到condition才需要去實現(xiàn)它。
  • tryAcquire(int):獨占方式。嘗試獲取資源,成功則返回true,失敗則返回false。
  • tryRelease(int):獨占方式。嘗試釋放資源,成功則返回true,失敗則返回false。
  • tryAcquireShared(int):共享方式。嘗試獲取資源。負(fù)數(shù)表示失??;0表示成功,但沒有剩余可用資源;正數(shù)表示成功,且有剩余資源。
  • tryReleaseShared(int):共享方式。嘗試釋放資源,如果釋放后允許喚醒后續(xù)等待結(jié)點返回true,否則返回false。

以ReentrantLock為例,state初始化為0,表示未鎖定狀態(tài)。A線程lock()時,會調(diào)用tryAcquire()獨占該鎖并將state+1。此后,其他線程再tryAcquire()時就會失敗,直到A線程unlock()到state=0(即釋放鎖)為止,其它線程才有機會獲取該鎖。當(dāng)然,釋放鎖之前,A線程自己是可以重復(fù)獲取此鎖的(state會累加),這就是可重入的概念。但要注意,獲取多少次就要釋放多么次,這樣才能保證state是能回到零態(tài)的。

再以CountDownLatch以例,任務(wù)分為N個子線程去執(zhí)行,state也初始化為N(注意N要與線程個數(shù)一致)。這N個子線程是并行執(zhí)行的,每個子線程執(zhí)行完后countDown()一次,state會CAS減1。等到所有子線程都執(zhí)行完后(即state=0),會unpark()主調(diào)用線程,然后主調(diào)用線程就會從await()函數(shù)返回,繼續(xù)后余動作。

一般來說,自定義同步器要么是獨占方法,要么是共享方式,他們也只需實現(xiàn)tryAcquire-tryRelease、tryAcquireShared-tryReleaseShared中的一種即可。但AQS也支持自定義同步器同時實現(xiàn)獨占和共享兩種方式,如ReentrantReadWriteLock。

6、鎖的分類:公平鎖和非公平鎖,樂觀鎖和悲觀鎖

  • 公平鎖:當(dāng)線程A獲取訪問該對象,獲取到鎖后,此時內(nèi)部存在一個計數(shù)器num+1,其他線程想訪問該對象,就會進(jìn)行排隊等待(等待隊列最前一個線程處于待喚醒狀態(tài)),直到線程A釋放鎖(num = 0),此時會喚醒處于待喚醒狀態(tài)的線程進(jìn)行獲取鎖的操作,一直循環(huán)。如果線程A再次嘗試獲取該對象鎖時,會檢查該對象鎖釋放已經(jīng)被占用,如果還是當(dāng)前線程占用鎖,則直接獲得鎖,不用進(jìn)入排隊。
  • 非公平鎖:當(dāng)線程A在釋放鎖后,等待對象的線程會進(jìn)行資源競爭,競爭成功的線程將獲取該鎖,其他線程繼續(xù)睡眠。

公平鎖是嚴(yán)格的以FIFO的方式進(jìn)行鎖的競爭,但是非公平鎖是無序的鎖競爭,剛釋放鎖的線程很大程度上能比較快的獲取到鎖,隊列中的線程只能等待,所以非公平鎖可能會有“饑餓”的問題。但是重復(fù)的鎖獲取能減小線程之間的切換,而公平鎖則是嚴(yán)格的線程切換,這樣對操作系統(tǒng)的影響是比較大的,所以非公平鎖的吞吐量是大于公平鎖的,這也是為什么JDK將非公平鎖作為默認(rèn)的實現(xiàn)。

  • 悲觀鎖:總是假設(shè)最壞的情況,每次想要使用數(shù)據(jù)的時候就恰好別人也要修改數(shù)據(jù),一切是以安全第一,所以在每次操作資源的時候都會先加鎖,不管有沒有人搶,然后獨占資源。Java中synchronized和ReentrantLock等獨占鎖就是悲觀鎖思想的實現(xiàn)
  • 樂觀鎖:樂觀鎖和悲觀鎖剛好相反,自己使用資源的時候沒有人搶,所以不需要上鎖。樂觀鎖的實現(xiàn)方案一般來說有兩種:版本號機制 和 CAS實現(xiàn) 。樂觀鎖多適用于多度的應(yīng)用類型,這樣可以提高吞吐量。

7、CAS

CAS(Compare And Swap),即比較并交換。是解決多線程并行情況下使用鎖造成性能損耗的一種機制,CAS操作包含三個操作數(shù)——內(nèi)存位置(V)、預(yù)期原值(A)和新值(B)。如果內(nèi)存位置的值與預(yù)期原值相匹配,那么處理器會自動將該位置值更新為新值。否則,處理器不做任何操作。無論哪種情況,它都會在CAS指令之前返回該位置的值。CAS有效地說明了“我認(rèn)為位置V應(yīng)該包含值A(chǔ);如果包含該值,則將B放到這個位置;否則,不要更改該位置,只告訴我這個位置現(xiàn)在的值即可。sun.misc.Unsafe 類提供了硬件級別的原子操作來實現(xiàn)這個CAS。java.util.concurrent 包下的大量類都使用了這個 Unsafe.java 類的CAS操作。Unsafe 包是C++的接口實現(xiàn),直接可以訪問計算機的內(nèi)存等敏感操作,所以標(biāo)記為Unsafe。

CAS 是直接調(diào)用計算機的硬件指令,是硬件級別的線程同步,也是一種樂觀鎖。

8、總結(jié)

從整體上說了下AQS,沒有深入到代碼層級,先理解思想,后看具體實現(xiàn)。你理解了嗎?下期具體分析一個CountDownLatch 源碼,從細(xì)節(jié)理解AQS。

本篇文章就到這里了,希望能對你有所幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • springboot攔截器過濾token,并返回結(jié)果及異常處理操作

    springboot攔截器過濾token,并返回結(jié)果及異常處理操作

    這篇文章主要介紹了springboot攔截器過濾token,并返回結(jié)果及異常處理操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • 詳解使用SSM實現(xiàn)簡單工作流系統(tǒng)之實現(xiàn)篇

    詳解使用SSM實現(xiàn)簡單工作流系統(tǒng)之實現(xiàn)篇

    這篇文章主要介紹了使用SSM實現(xiàn)簡單工作流系統(tǒng)之實現(xiàn)篇,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12
  • SpringMVC空指針異常NullPointerException解決及原理解析

    SpringMVC空指針異常NullPointerException解決及原理解析

    這篇文章主要介紹了SpringMVC空指針異常NullPointerException解決及原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • Java獲取鏈接上的參數(shù)三種方法舉例

    Java獲取鏈接上的參數(shù)三種方法舉例

    在Java中,我們經(jīng)常需要從URL鏈接中獲取參數(shù),下面這篇文章主要給大家介紹了關(guān)于Java如何獲取鏈接上參數(shù)的三種方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-06-06
  • idea快速搭建spring cloud注冊中心與注冊的方法

    idea快速搭建spring cloud注冊中心與注冊的方法

    這篇文章主要介紹了idea快速搭建spring cloud注冊中心與注冊的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • 解讀Java和JavaScript區(qū)別與聯(lián)系

    解讀Java和JavaScript區(qū)別與聯(lián)系

    這篇文章主要介紹了解讀Java和JavaScript區(qū)別與聯(lián)系,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Java實現(xiàn)HTML轉(zhuǎn)為Word的示例代碼

    Java實現(xiàn)HTML轉(zhuǎn)為Word的示例代碼

    本文以Java代碼為例為大家詳細(xì)介紹如何實現(xiàn)將HTML文件轉(zhuǎn)為Word文檔(.docx、.doc)。在實際開發(fā)場景中可參考此方法來轉(zhuǎn)換,感興趣的可以了解一下
    2022-06-06
  • 聊聊mybatis sql的括號問題

    聊聊mybatis sql的括號問題

    這篇文章主要介紹了mybatis sql的括號問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Java多線程下載網(wǎng)圖的完整案例

    Java多線程下載網(wǎng)圖的完整案例

    這篇文章主要給大家介紹了關(guān)于Java多線程下載網(wǎng)圖的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Spring Boot整合Spring Data Jpa代碼實例

    Spring Boot整合Spring Data Jpa代碼實例

    這篇文章主要介紹了Spring Boot整合Spring Data Jpa代碼實例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-11-11

最新評論