hashmap、hashtable、ConCurrentHashMap分析
来源:互联网 发布:网络运维工程师招聘 编辑:程序博客网 时间:2024/06/10 08:23
优秀博文:http://www.cnblogs.com/yydcdut/p/3959815.html
线程不安全的hashmap
hashmap是线程不安全,在多线程情况下,使用hashmap的put操作会引起死循环。所以在并发情况下不能使用HashMap
线程安全的hashtable
但是在多线程情况下效率极低。因为synchronized是针对整张Hash表的,即每次锁住整张表让线程独占,所有访问hashtable的线程都对同一个锁进行竞争。
线程安全且效率高的ConCurrentHashMap
采用了锁分离技术,每个段都有一个锁,所以可以在一定程度上保证写并发。读操作不需要加锁,所以可以实现完全读并发。
内部结构
ConCurrentHashMap内部使用段(Segment),每个段都是一个小的hashtable(其中包含多个HashEntry[])。每个段都有自己独立的锁,只要多个修改操作发生在不同的段上,就可以实现并发。(读操作可以完全实现并发,因为读不加锁)
但是!
有些方法需要跨段,如size() containsValue()。这些方法可能需要锁定整个表。因此,需要按顺序锁定所有段,操作完毕后,又需要按顺序释放所有锁。(如果这里加锁以及释放锁没有按顺序,可能会出现死锁。在ConCurrentHashMap内部,段数组是声明为final的,但是这并不保证段数组成员也是final的)
源码分析
static final class HashEntry<K,V> { final K key; final int hash; volatile V value; final HashEntry<K,V> next; }
如上所示,除value之外,其他成员都是final的,这意味者只能从hash表的头部添加或删除节点(因为需要需改next引用值,所有节点的修改只能从头部开始,put操作也一律添加到头部)
为了确保读操作能够读取到最新的值,将value设置为volatile,这就避免了加锁。
但是对于remove操作,可能需要从中间删除一个节点,这就需要将要删除节点的前面所有节点整个复制一遍,最后一个节点指向要删除结点的下一个结点。
get方法:
public V get(Object key) { int hash = hash(key); // throws NullPointerException if key null return segmentFor(hash).get(key, hash);}
可见,get方法并没有加锁,交给segment去寻找。
V get(Object key, int hash) { if (count != 0) { HashEntry<K,V> e = getFirst(hash); while (e != null) { if (e.hash == hash && key.equals(e.key)) { V v = e.value; if (v != null) return v; return readValueUnderLock(e); } e = e.next; } } return null;}
它也没有用锁实现数据同步。归根结底就是因为value设置为volatile
get操作第一步访问count变量(该变量声明为volatile)。所有的结构修改操作都会在最后一步写count变量,(这就保证了get操作能够获取到最新的值)
- hashmap、hashtable、ConCurrentHashMap分析
- HashMap,HashTable,HashSet,ConcurrentHashMap的分析比较
- HashMap、Hashtable、ConcurrentHashMap等深入分析
- HashMap,HashTable,ConcurrentHashMap,ConcurrentSkipListMap
- HashMap、ConcurrentHashMap、HashTable、HashSet
- ConcurrentHashMap、HashMap、HashTable区别
- HashMap、HashTable、ConcurrentHashMap、Queue
- HashMap HashTable ConcurrentHashmap
- hashMap ,hashTable ,concurrentHashMap区别
- HashMap、HashTable、ConcurrentHashMap
- HashMap HashTable ConcurrentHashMap区别
- HashMap HashTable和ConcurrentHashMap
- Hashtable,HashMap,ConcurrentHashMap
- HashMap HashTable ConCurrentHashMap
- hashmap 、hashtable、 ConcurrentHashMap总结
- HashTable/HashMap/ConcurrentHashMap
- HashMap、HashTable、ConcurrentHashMap
- HashMap、Hashtable与ConcurrentHashMap
- 几种常用Gradient descent optimization算法详解
- HDU 1548 A strange lift bfs 宽搜解析
- Random方法,列表元组的使用
- Git查看、删除、重命名远程分支和tag
- springboot动态修改系统日志级别
- hashmap、hashtable、ConCurrentHashMap分析
- poj 3186 && bzoj 1652: [Usaco2006 Feb]Treats for the Cows(DP)
- bzoj1977 [BeiJing2010组队]次小生成树 倍增
- Paper:Learning from Imbalanced Data
- JAVA Runtime.addShutdownHook()方法
- U3D移动平台的资源路径问题
- cs231n-之训练过程参数监控(占个位,回来补)
- Eclipse下导入外部jar包的3种方式
- spring支持五种事务隔离和六种事务传播属性