學習ConcurrentHashMap併發寫機制

2022-07-05 02:21:09 字數 1695 閱讀 1592

上篇文章講了 unsafe 類中 cas 的實現,其實是在為這篇文章打基礎。不太熟悉的小夥伴請移步unsafe 中 cas 的實現。本篇文章主要基於openjdk8來做原始碼解析。

concurrenthashmap 基於 hashmap 實現。

jdk1.7 和 jdk1.8 作為併發容器在實現上是有差別的。jdk1.7 通過 segment 分段鎖實現,而 jdk1.8 通過 cas+synchronized 實現。

在 concurrenthashmap 中使用了 unsafe 方法,通過直接操作記憶體的方式來保證併發處理的安全性,使用的是硬體的安全機制。

private static final sun.misc.unsafe u;

private static final long sizectl;

private static final long transferindex;

private static final long basecount;

private static final long cellsbusy;

private static final long cellvalue;

private static final long abase;

private static final int ashift;

static catch (exception e)

}static final nodetabat(node tab, int i)

// cas 將node插入bucket

static final boolean castabat(node tab, int i,

nodec, nodev)

static final void settabat(node tab, int i, nodev)

還是老規矩,先上流程圖幫助閱讀原始碼。

主體原始碼如下:

public v put(k key, v value) 

/** implementation for put and putifabsent */

final v putval(k key, v value, boolean onlyifabsent)

// 如果在進行擴容操作,則先擴容

else if ((fh = f.hash) == moved)

tab = helptransfer(tab, f);

// 否則,存在hash衝突

else

nodepred = e;

// 尾插法插入

if ((e = e.next) == null) }}

// 如果是樹節點,遍歷紅黑樹

else if (f instanceof treebin) }}

}if (bincount != 0) }}

addcount(1l, bincount);

return null;

}

put 操作過程如下:

下邊的示意圖來自網路

學習學習再學習

如果乙個技能足夠複雜 比如從零學程式設計 那就不要指望讀完一本書就可以打天下。多買幾本書同類的書 因為每個作者的出發點是不一樣的,哪怕對同乙個概念都有不同的解釋說明。理解知識的重要過程之一就如牛的反芻一樣,要嚼一遍 嚥下去 再吐出來 再嚼一遍 再嚥下去 所以,既然一本書可以讀幾遍,那麼同一話題多應該...

學習 學習 再學習

原本要使用vs2005開發乙個b s專案的,沒有想到只能先暫時停停了,居然跟不上技術的發展了,呵呵,一直使用delphi delphi也沒能跟上 沒有想到轉到vs2005上竟然有這麼多要學的東西,當然目的是了做乙個好的系統。最近一直在學習asp.net ajax,雖然專案停了,但是我覺得值得,有很多...

只是學習 學習 再學習

通過做 讓我學會了很多東西 什麼 flash div css html js as 雖然都只是皮毛 不過 算是了解那麼一點點吧 哈哈 我還突然發現 我的 數學和英語 進步了不少 而且還都是很實用的 比在學校的進步可快多了 那句話說的很不錯 在你了解了一些皮毛之後你會發現很多東西你都必須去學。因為少一...