java8 ConcurrentHashMap
来源:互联网 发布:音乐后期制作软件手机 编辑:程序博客网 时间:2024/06/05 07:31
node结构
static class Node<K,V> implements Map.Entry<K,V> { final int hash; final K key; volatile V val; volatile Node<K,V> next; Node(int hash, K key, V val, Node<K,V> next) { this.hash = hash; this.key = key; this.val = val; this.next = next; } public final K getKey() { return key; } public final V getValue() { return val; } public final int hashCode() { return key.hashCode() ^ val.hashCode(); } public final String toString(){ return key + "=" + val; } public final V setValue(V value) { throw new UnsupportedOperationException(); } public final boolean equals(Object o) { Object k, v, u; Map.Entry<?,?> e; return ((o instanceof Map.Entry) && (k = (e = (Map.Entry<?,?>)o).getKey()) != null && (v = e.getValue()) != null && (k == key || k.equals(key)) && (v == (u = val) || v.equals(u))); } /** * Virtualized support for map.get(); overridden in subclasses. */ Node<K,V> find(int h, Object k) { Node<K,V> e = this; if (k != null) { do { K ek; if (e.hash == h && ((ek = e.key) == k || (ek != null && k.equals(ek)))) return e; } while ((e = e.next) != null); } return null; } }
static final int MOVED = -1; // hash for forwarding nodes forwardNode类型节点的hash static final int TREEBIN = -2; // hash for roots of trees 树形节点hash/** * Table initialization and resizing control. When negative, the 负数时候是在初始化或者重建 * table is being initialized or resized: -1 for initialization, * else -(1 + the number of active resizing threads). Otherwise, * when table is null, holds the initial table size to use upon * creation, or 0 for default. After initialization, holds the * next element count value upon which to resize the table. */ private transient volatile int sizeCtl;
put以及transfer过程:
1、不允许Null的key或者value
2、一个死循环用来put,何时put成功何时跳出,第一次put初始化table
3、tabAt(tab, i = (n - 1) & hash)找到当前node应该在table位置处的node,若是为null,不加锁利用casTabAt()方法放进去,break
4、如果这个node不是null,而是forwardNode类型,说明这个节点以及被transfer了,这使用helpTransfer(tab, f);帮助transfer,得到新的table,进行下一次循环put
5、如果找到的node不是null,也不是forwardNode类型,即找到了链表或者tree的头结点,对这个头结点加锁
遍历链表或者tree,比较key和hash,找到则替换value,到尾节点则新加一个节点
6、transfer扩容方法,允许多个线程扩容,利用了private transient volatile Node<K,V>[] nextTable;以及forwardNode
一个线程扩容时候会把nextTable指向当前操作nextTab,另一个线程在put时候遇到forwardNode节点时候,使用helpTransfer,会先拿到nextTable,然后进入扩容方法,多个线程扩容操作的nextTable会是一个。
每次处理完table中i出节点,就会把这处的节点置为forwardNode节点类型
遍历到空节点,也置为forwardNode节点类型
如果遍历到forwardNode类型,则跳过不处理
拷贝节点以及list就跟hashmap类似,不过这个过程对头结点做了加锁
//原子操作 //可以理解为得到tab的i处节点 static final <K,V> Node<K,V> tabAt(Node<K,V>[] tab, int i) { return (Node<K,V>)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE); } //如果tab的i处节点为c,则更新为v static final <K,V> boolean casTabAt(Node<K,V>[] tab, int i, Node<K,V> c, Node<K,V> v) { return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v); } //<span><span class="comment">设置节点位置的值</span><span> </span></span> static final <K,V> void setTabAt(Node<K,V>[] tab, int i, Node<K,V> v) { U.putObjectVolatile(tab, ((long)i << ASHIFT) + ABASE, v); }
- java8 ConcurrentHashMap
- ConcurrentHashMap--Java8
- Java8-ConcurrentHashMap
- ConcurrentHashMap源码分析--Java8
- ConcurrentHashMap源码分析--Java8
- ConcurrentHashMap学习笔记(Java8)
- Java8—ConcurrentHashMap分析
- java8中concurrentHashmap的改进
- Java8下的ConcurrentHashMap新操作
- java8中对ConcurrentHashMap的改进
- ConcurrentHashMap与红黑树实现分析Java8
- Java8---4.对HashMap和ConcurrentHashMap的改进
- JDK源码-java8-ConcurrentHashMap的实现原理与应用
- 【Java8源码分析】并发包-ConcurrentHashMap(一)
- 【Java8源码分析】并发包-ConcurrentHashMap(二)
- Java并发学习(十九)-Java8中ConcurrentHashMap分析
- ConcurrentHashMap
- ConcurrentHashMap
- 第十三周项目5:立体类族共有的抽象类
- |NOIOJ|二分|04:网线主管
- 学会编写Android Studio插件 别停留在用的程度了
- Linux下的C++程序崩溃时打印崩溃信息
- EditText中imeOptions属性使用及设置无效解决
- java8 ConcurrentHashMap
- 关于服务程序开发的几点注意事项
- SVM入门(一)至(三)Refresh
- iScroll 左右滑动获取索引
- vim编辑器的使用
- webview调用js
- 我的助理辞职了!——看完后大家对这篇文章应该很有感触
- Sqlyog之excel数据导入方法
- C++ I/O库流状态标志位