ConcurrentHashMap
来源:互联网 发布:asp.net源码 网络 编辑:程序博客网 时间:2024/05/21 07:59
1 map的分类
(1)非线程安全的map:
HashMap
(2)线程安全的map:
HashTable Collections.synchronizedMap(new HashMap<K, V>()) ConcurrentHashMap
2 各个map的比较
(1)HashMap:非线程安全的,适用于单线程环境,因为不存在锁和阻塞,所以效率较高
(2)HashTable:线程安全的,使用synchronized关键字修饰方法,实现了线程安全。单线程环境下,建议使用HashMap,因为锁的管理也需要开销。
(3)Collections.synchronizedMap(map):线程安全的,使用Collections里面的静态方法将非线程安全的map封装成线程安全的map。效率和应用场景方面与HashTable相同。
(4)ConcurrentHashMap:一个专用于高并发的map。使用了分段锁机制,减小锁粒度,因此提高了并发度。
3 ConcurrentHashMap浅析
3.1 底层存储结构图
3.2 分段锁
ConcurrentHashMap允许多个修改操作并发进行,其关键在于使用了锁分离技术。它使用了多个锁来控制对hash表的不同部分进行的修改。ConcurrentHashMap内部使用段(Segment)来表示这些不同的部分,每个段其实就是一个小的hash table,它们有自己的锁。只要多个修改操作发生在不同的段上,它们就可以并发进行。
ConcurrentHashMap是专门为线程并发而设计的,它的get操作是无锁的,它的put操作只在对应的segment上加锁。因此,它的整体性能优于同步的HashMap(对整个table加锁)。
默认情况下,ConcurrentHashMap拥有16个段,因此,足够幸运的话,可以同时接受16个线程同时put(插入到不同段中)。
3.3 弱一致性问题
由于get方法,并没有加锁,因此肯定会存在一致性的问题。get方法并没有加锁,因此也不会和put方法冲突,当多个线程同时操作该map时,有的线程get,有的线程put,因为我们并不确定put方法执行完了没(可能只执行了一部分语句,后面真正改内存的语句还没有执行),所以get不一定能够得到最新值(put还没写进去,叫最新值也不是很妥当)。但是,一旦put操作执行完,那么get一定可以感知到最新值,因为Node的val和next字段都是volatile的:
static class Node<K,V> implements Map.Entry<K,V> { final int hash; final K key; volatile V val; volatile Node<K,V> next;}
同理,很多全局方法都存在弱一致性问题,比如size等。
ConcurrentHashMap的弱一致性主要是为了提升效率,是一致性与效率之间的一种权衡。要成为强一致性,就得到处使用锁,甚至是全局锁。
上面仅是个人的一点浅见,有不妥之处欢迎指出。
0 0
- ConcurrentHashMap
- ConcurrentHashMap
- ConcurrentHashMap
- ConcurrentHashMap
- ConcurrentHashMap
- ConcurrentHashMap
- ConcurrentHashMap
- ConcurrentHashMap
- ConcurrentHashMap
- ConcurrentHashMap
- ConcurrentHashMap
- ConcurrentHashMap
- ConcurrentHashMap
- ConcurrentHashMap
- ConcurrentHashMap
- concurrenthashmap
- ConcurrentHashMap
- ConcurrentHashMap
- Hibernate主键生成策略总结
- windows平台下搭建tigase服务器
- $(( )) 與 $( ) 還有${ } 区别
- 查找path路径下的所有目录和文件
- Everyday Mininet Usage
- ConcurrentHashMap
- 服务器性能优化配置建议
- 快速排序
- DEV控件:gridControl常用属性设置
- 二年编程之路
- Oracle 分区表
- Linux下给mysql创建用户分配权限
- realpath
- springMVC整合Freemarker例子