- 再哈希法:如果hash出的index已经有值 , 就再hash , 不行继续hash , 直至找到空的index位置 。
- **开放地址法:**如果hash出的index已经有值 , 通过算法在它前面或后面的若干位置寻找空位 。
- 建立公共溢出区: 把冲突的hash值放到另外一块溢出区 。
- 链式地址法: 把产生hash冲突的hash值以链表形式存储在index位置上 。HashMap的解决方案 。
/*** ThreadLocalMap is a customized hash map suitable only for* maintaining thread local values. No operations are exported* outside of the ThreadLocal class. The class is package private to* allow declaration of fields in class Thread. To help deal with* very large and long-lived usages, the hash table entries use* WeakReferences for keys. However, since reference queues are not* used, stale entries are guaranteed to be removed only when* the table starts running out of space.* */static class ThreadLocalMap { static class Entry extends WeakReference<ThreadLocal<?>> { /** The value associated with this ThreadLocal. */ Object value; Entry(ThreadLocal<?> k, Object v) { super(k); value = v; } } /** * The table, resized as necessary. * table.length MUST always be a power of two. * table.length必须是2的幂次 */ private Entry[] table; /** * The number of entries in the table. * table实际已经存放#Entry的数量 */ private int size = 0; /** * The next size value at which to resize. * table扩容的阈值 , 初始threshold = length * 2 / 3 , 当size>threshold*3/4时就扩容 */ private int threshold; /** * The initial capacity -- MUST be a power of two. * table 的默认容量 */ private static final int INITIAL_CAPACITY = 16; /** * Set the value associated with key. * * @param key the thread local object * @param value the value to be set */ private void set(ThreadLocal<?> key, Object value) { Entry[] tab = table; int len = tab.length; //计算key的角标index 。就是用key的threadLocalHashCode & (len-1)等效于key.threadLocalHashCode%len //只是&要比%效率高 , 它们之所以可以等效 , 因为len是2的n次幂 。 //threadLocalHashCode并不影响读懂这块代码 , 放在后面详说 int i = key.threadLocalHashCode & (len-1); //开放地址方法 , 循环tab for (Entry e = tab[i]; e != null; e = tab[i = nextIndex(i, len)]) { ThreadLocal<?> k = e.get(); //key相同 , 更新value if (k == key) { e.value = value; return; } //key为空 , 说明ThreadLocal实例被回收了 , 用新key-value替代 if (k == null) { replaceStaleEntry(key, value, i); return; } } //table[i]=null 新建一个Entity , ++size tab[i] = new Entry(key, value); int sz = ++size; if (!cleanSomeSlots(i, sz) && sz >= threshold) rehash(); } //整理table private void rehash() { //删除table[]陈旧元素 expungeStaleEntries(); //size依然大于3/4 threshold , 扩容 if (size >= threshold - threshold / 4) resize(); }/** * Expunge all stale entries in the table. * 删除table[]所有key==null的entity*/ private void expungeStaleEntries() { Entry[] tab = table; int len = tab.length; for (int j = 0; j < len; j++) { Entry e = tab[j]; if (e != null && e.get() == null) expungeStaleEntry(j); } } /** * Double the capacity of the table. * 扩容为原数组的2倍 */ private void resize() { Entry[] oldTab = table; int oldLen = oldTab.length; int newLen = oldLen * 2; //创建2倍容量的新数组 Entry[] newTab = new Entry[newLen]; int count = 0; for (int j = 0; j < oldLen; ++j) { Entry e = oldTab[j]; if (e != null) { //如果线程的 ThreadLocal<?> k = e.get(); if (k == null) { e.value = null; // Help the GC } else { //计算新数组index int h = k.threadLocalHashCode & (newLen - 1); while (newTab[h] != null) h = nextIndex(h, newLen); newTab[h] = e; count++; } } } setThreshold(newLen); size = count; table = newTab; } //返回当前线程对应的ThreadLocalMap ThreadLocalMap getMap(Thread t) { return t.threadLocals; }}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 绿茶有多少茶叶种类,特征描述其绿茶新旧以及高山平底绿茶
- Springboot——自动配置原理
- 漫话三国茶事,三国晋朝的茶发展及文化
- 百合绿茶介绍,麦冬百合甘草茶制作及功效介绍
- 白茶的白毫是怎么回事,白茶的种类及基本制作工艺先容
- 灵芝茶功效及作用介绍,红菊花茶的功效与作用
- 绿茶制作及种类先容,茉莉花茶的基本先容
- 2022年杭州亚运会场馆建设进度?2022杭州亚运会项目及场地_1
- 2021苏锡常镇高三二模语文作文范文?2021届苏锡常高三二模作文题及范文_1
- 包种茶历史发展情况,绿杨春茶叶的历史渊源及发展