ConcurrentHashMap原始碼詳解

2021-08-22 00:24:07 字數 3962 閱讀 5094

成員變數

private

static

final

int maximum_capacity = 1

<< 30;

private

static

final

int default_capacity = 16;

static

final

int max_array_size = integer.max_value - 8;

private

static

final

int default_concurrency_level = 16;

private

static

final

float load_factor = 0.75f;

static

final

int treeify_threshold = 8;

static

final

int untreeify_threshold = 6;

static

final

int min_treeify_capacity = 64;

private

static

final

int min_transfer_stride = 16;

private

static

int resize_stamp_bits = 16;

private

static

final

int max_resizers = (1

<< (32 - resize_stamp_bits)) - 1;

private

static

final

int resize_stamp_shift = 32 - resize_stamp_bits;

static

final

int moved = -1; // hash for forwarding nodes

static

final

int treebin = -2; // hash for roots of trees

static

final

int reserved = -3; // hash for transient reservations

static

final

int hash_bits = 0x7fffffff; // usable bits of normal node hash

//儲存key-value的node節點

static class nodeimplements map.entry

}// 初始化發生在第一次插入操作,預設大小為16的陣列,用來儲存node節點資料,擴容時大小總是2的冪次方。

transient

volatile node table;

// 預設為null,擴容時新生成的陣列,其大小為原陣列的兩倍。

private

transient

volatile node nexttable;

private

transient

volatile

long basecount;

// sizectl預設為0,用來控制table的初始化和擴容操作

/*-1 代表table正在初始化

-n 表示有n-1個執行緒正在進行擴容操作

另外:1 如果table未初始化,表示table需要初始化的大小

2 如果table初始化完成,表示table的容量,預設是table大小的0.75倍

*/private

transient

volatile

int sizectl;

private

transient

volatile

int transferindex;

private

transient

volatile

int cellsbusy;

private

transient

volatile countercell countercells;

private

transient keysetviewkeyset;

private

transient valuesviewvalues;

private

transient entrysetviewentryset;

//下面三個方法為原子操作,分別對應volatile的取值,cas操作,賦值

static

final

nodetabat(node tab, int i)

static

final

boolean castabat(node tab, int i,

nodec, nodev)

static

final

void settabat(node tab, int i, nodev)

構造方法初始化
//建立乙個物件,什麼都不做

public

concurrenthashmap()

//傳入容量值,需要將這個值變為比這個值大的2^n

public

concurrenthashmap(int initialcapacity)

public

concurrenthashmap(map<? extends k, ? extends v> m)

public

concurrenthashmap(int initialcapacity, float loadfactor)

public

concurrenthashmap(int initialcapacity,

float loadfactor, int concurrencylevel)

table初始化
//table的初始化不在構造方法中發生,而是在第一次put時,呼叫了inittable方法

private

final node inittable()

} finally

break;}}

return tab;

}

put方法
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) // 如果hash值為-1,說明正在進行擴容操作

tab = helptransfer(tab, f);//資料遷移**不太容易,日後再說

else

// 到了鍊錶的最末端,將這個新值放到鍊錶的最後面

nodepred = e;

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

else

if (f instanceof treebin) }}

}if (bincount != 0) }}

addcount(1l, bincount);

return

null;

}

get方法
public v get(object key) 

else

if (eh < 0)

return (p = e.find(h, key)) != null ? p.val : null;

while ((e = e.next) != null)

}return

null;

}

ConcurrentHashMap原始碼分析

hashmap 先說hashmap,hashmap是執行緒不安全 的,在併發環境下,可能會形成環狀鍊錶 hashtable hashtable和hashmap的實現原理幾乎一樣,差別無非是1.hashtable不允許key和value為null 2.hashtable是執行緒安全的。但是hashta...

concurrentHashMap原始碼分析

concurrenthashmap是hashmap的執行緒安全版本,內部也是使用 陣列 鍊錶 紅黑樹 的結構來儲存元素。相比於同樣執行緒安全的hashtable來說,效率等各方面都有極大地提高。在這裡可以使用上篇那個 進行測試,根據結果可以知道concurrenthashmap是執行緒安全的,由於分...

ConcurrentHashMap原始碼分析

concurrenthashmap原始碼分析concurrenthashmap是乙個執行緒安全的 高可用hashmp 本部落格基於jdk1.8concurrenthash實現原理進行分析,如有不對,敬請斧 正。1 資料結構知識點 1 hash演算法 2 鍊錶 3 陣列 4 二叉樹 紅黑二叉樹 2 多...