首页天道酬勤linkhashmap多线程修改(java hashmap 扩容)

linkhashmap多线程修改(java hashmap 扩容)

admin 12-04 11:01 214次浏览

今天我们要讲的是收藏,其实和锁有关系。让我们一起来看看。

一.导言

1.这是什么?

ConcurrentHashMap是Java5中新添加的线程安全Map集,可以用来替换HashTable。至于ConcurrentHashMap如何提高效率,大部分人可能只是知道它使用了多个锁,而不是HashTable中的单个锁,也就是锁剥离技术。

2.为什么呢?

为什么不用HashMap?

Hashmap基本数据加链表。根据关键字获取哈希值,然后计算数组下标。如果多个键对应同一个下标,用链表把它们串在一起,新插入的键在前面。而hashmap在单线程的情况下效率更高。

但是在多线程环境下,使用Hashmap进行put操作会造成无限循环,导致CPU利用率接近100%,因此HashMap无法在并发情况下使用。

为什么不使用哈希表?

Hastable容器使用synchronized来确保线程安全,但是HashTable在线程竞争激烈的情况下效率非常低。因为当一个线程访问哈希表的同步方法时,其他线程在访问哈希表的同步方法时可能会进入阻塞或轮询状态。如果线程1使用put添加元素,那么线程2不仅可以用put方法添加元素,还可以用get方法获取元素,所以竞争越激烈,效率越低。

为什么要使用ConcurrentHashMap?

hastable容器在高度竞争的并发环境中效率低下的原因是,所有访问hastable的线程都必须争夺同一个锁。如果容器中有多个锁,并且每个锁用于锁定容器中的一部分数据,那么当多线程访问容器中不同数据段的数据时,线程之间就不会有锁竞争,从而有效提高了并发访问的效率。这是ConcurrentHashMap使用的锁分段技术。首先,将数据划分为段进行存储,然后为每个数据段分配一个锁。当一个线程占用锁来访问一段数据时,其他线程也可以访问其他数据段。

二、深入分析

1.结构图分析

ConcurrentHashMap和HashTable的主要区别在于锁的粒度以及如何锁,可以简单理解为将一个大的Hashtable拆分成多个,形成锁分离。哈希表是通过锁定整个哈希表来实现的。

从图中可以看出,ConcurrentHashMap在内部被分成许多段,每个段都有一个锁,然后在每个段下有许多HashEntry列表数组(继承可重入锁)。对于一个键,它需要经过三次哈希运算(为什么需要哈希三次,后面会详细解释)才能最终定位这个元素的位置。这三个散列是:

对于一个密钥,首先进行哈希运算得到哈希值h1,即H1=hash1(密钥);

第二次散列h1的高位,得到散列值h2,即H2=has H2(H1的高位),即Segment元素被放置在可以由H2确定的地方;

对得到的h1进行第三次散列,得到散列值h3,即h3=hash3(h1),元素放在其中的HashEntry可以由h3确定。

2.实施原则

ConcurrentHashMap将Map分成n个段(默认为16个),其中段是线程同步的,这相当于被分成n个Hashtable段。实现Put方法时,键值通过正常哈希后,还得再经过segmentForHash算法,该段用于分配特定的防盗。之后,如果线程在计算后也放在这个Segment中,需要先获取锁。如果计算出应该放在其他段,则正常执行,不会影响效率,从而实现线程安全。ConcurrentHashMap使用锁分离技术,因此只要多个修改操作没有发生在同一个Segment中,就可以并发执行。

有些方法需要跨节,比如size()和containsValue(),需要锁定整个表,而不是只锁定某个节,这就需要按顺序锁定所有节,然后在操作后按顺序释放所有节的锁。在这里,“按顺序”非常重要,否则很有可能陷入僵局。在ConcurrentHashMap中,段数组是最终的,它的成员变量实际上是最终的。但是,仅仅将数组声明为final并不能保证数组成员是final,这需要实现保证。这确保了死锁不会发生,因为获取锁的顺序是固定的。

3.源代码的详细解释

这里就不细说了。网上有很多。推荐Java并外包学习八ConcurrentHashMap的深度分析

总结:

事实上,这个类在我们项目的缓存中使用。ConcurrentHashMap用于存储一些常用的信息。因为它用于并发情况,考虑到性能问题,ConcurrentHashMap类是首选。不过我建议大家多看看源代码,对大家会有很大的好处。

SpringBoot官网构建Java Web动态网站开发实例分析如何使用java.util.logging.SimpleFormatter为Tomcat的控制台日志指定单独的日志格式请提交或存储任何更改UCloud新一代混合云基础架构平台“金翼专区”
spring事务面试(java事务面试题) spring中文(spring 线程池)
相关内容