Java源碼解析ConcurrentHashMap的初始化
首先看一下代碼
private final Node<K,V>[] initTable() {
Node<K,V>[] tab; int sc;
while ((tab = table) == null || tab.length == 0) { // 第一次檢查
if ((sc = sizeCtl) < 0)
Thread.yield(); // lost initialization race; just spin
else if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
try {
if ((tab = table) == null || tab.length == 0) {// 第二次檢查
int n = (sc > 0) ? sc : DEFAULT_CAPACITY;
@SuppressWarnings("unchecked")
Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];
table = tab = nt;
sc = n - (n >>> 2);
}
} finally {
sizeCtl = sc;
}
break;
}
}
return tab;
}
ConcurrentHashMap在初始化時,如何進(jìn)行多線程間的同步?
ConcurrentHashMap在初始化時,首先會判斷,哈希表是否已經(jīng)初始化了。如果沒有,則嘗試進(jìn)行初始化。
首先會判斷sizeCtl的值。sizeCtl是用于多線程之間同步的一個互斥變量。當(dāng)sizeCtl < 0時,表示已經(jīng)有線程正在初始化哈希表或哈希表正在擴(kuò)容,此時,不能再進(jìn)行操作。
此處sizeCtl其實(shí)是實(shí)現(xiàn)了自旋鎖的功能。自旋鎖,即,獲取鎖失敗時,讓出CPU,稍后再進(jìn)行嘗試,重復(fù)這個過程,直到獲得到鎖為止。讓出CPU的動作,是通過java中的Thread.yield()來實(shí)現(xiàn)的。在學(xué)校學(xué)習(xí)java的時候曾經(jīng)接觸過線程的這個方法,但當(dāng)時不明白什么場景下會用到。原來,Thread.yield()方法可以用來實(shí)現(xiàn)自旋鎖。
這里,可以提出一個問題,自選鎖方式和死循環(huán)方式來判斷sizeCtl的值,有什么不同?
當(dāng)然是效率的不同。死循環(huán)時,程序會頻繁讀取sizeCtl的值,在滿足條件之前,會浪費(fèi)很多CPU周期。而自選鎖的效率更高,因?yàn)楫?dāng)它判斷sizeCtl不滿足條件時,會主動讓出CPU,此時,當(dāng)前線程會處于ready狀態(tài),等待下一次被處理器選中并執(zhí)行的機(jī)會。在這段時間里,其他的線程得以利用CPU周期。所以,自旋鎖的效率更高。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請查看下面相關(guān)鏈接
相關(guān)文章
SpringBoot整合Echarts實(shí)現(xiàn)用戶人數(shù)和性別展示功能(詳細(xì)步驟)
這篇文章主要介紹了SpringBoot整合Echarts實(shí)現(xiàn)用戶人數(shù)和性別展示,通過數(shù)據(jù)庫設(shè)計、實(shí)現(xiàn)數(shù)據(jù)訪問層、業(yè)務(wù)邏輯層和控制層的代碼編寫,以及前端頁面的開發(fā),本文詳細(xì)地介紹了SpringBoot整合Echarts的實(shí)現(xiàn)步驟和代碼,需要的朋友可以參考下2023-05-05
運(yùn)用java以及循環(huán)打印菱形詳細(xì)實(shí)例代碼
最近在看算法書的時候,看到有打印上三角的算法,然后要舉一反三,下面這篇文章主要介紹了運(yùn)用java以及循環(huán)打印菱形的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-10-10
java 基礎(chǔ)教程之多線程詳解及簡單實(shí)例
這篇文章主要介紹了java 基礎(chǔ)教程之多線程詳解及簡單實(shí)例的相關(guān)資料,線程的基本屬性、如何創(chuàng)建線程、線程的狀態(tài)切換以及線程通信,需要的朋友可以參考下2017-03-03
Java實(shí)現(xiàn)微信登錄并獲取用戶信息功能(開發(fā)流程)
這篇文章主要介紹了Java實(shí)現(xiàn)微信登錄并獲取用戶信息功能(開發(fā)流程),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-07-07
java通過RESTful API實(shí)現(xiàn)兩個項目之間相互傳輸數(shù)據(jù)
一些特殊場景中,兩個項目發(fā)布在不同的服務(wù)器,并且由于服務(wù)器限制特殊情況ip無法相通時進(jìn)行開放接口方式進(jìn)行數(shù)據(jù)傳輸,下面我們就來看看java通過RESTful API實(shí)現(xiàn)這一需求吧2025-09-09

