currenHashMap是jkd1.5引入的,其特点是:效率比Hashtable高,并发性比HashMap好。结合了两者的特点。

ConcurrentHashMap是一个线程安全的Hash Table,它的主要功能是提供了一组和HashTable功能相同但是线程安全的方法。ConcurrentHashMap可以做到读取数据不加锁,并且其内部的结构可以让其在进行写操作的时候能够将锁的粒度保持地尽量地小,不用对整个ConcurrentHashMap加锁。

ConcurrentHashMap为了提高本身的并发能力,在内部采用了一个叫做Segment的结构,一个Segment其实就是一个类Hash Table的结构,Segment内部维护了一个链表数组,我们用下面这一幅图来看下ConcurrentHashMap的内部结构:

从上面的结构我们可以了解到,ConcurrentHashMap定位一个元素的过程需要进行两次Hash操作,第一次Hash定位到Segment,第二次Hash定位到元素所在的链表的头部,因此,这一种结构的带来的副作用是Hash的过程要比普通的HashMap要长,但是带来的好处是写操作的时候可以只对元素所在的Segment进行加锁即可,不会影响到其他的Segment,这样,在最理想的情况下,ConcurrentHashMap可以最高同时支持Segment数量大小的写操作(刚好这些写操作都非常平均地分布在所有的Segment上),所以,通过这一种结构,ConcurrentHashMap的并发能力可以大大的提高。

HashMap中未进行同步考虑,而Hashtable则使用了synchronized,带来的直接影响就是可选择,我们可以在单线程时使用HashMap提高效率,而多线程时用Hashtable来保证安全。通过分析Hashtable就知道,synchronized是针对整张Hash表的,即每次锁住整张表让线程独占,安全的背后是巨大的浪费。

左边便是Hashtable的实现方式---锁整个hash表;而右边则是ConcurrentHashMap的实现方式---段锁。它使用了多个锁来控制对hash表的不同部分进行的修改。 ConcurrentHashMap将hash表分为16段(默认值),诸如get,put,remove等常用操作只锁当前需要用到的段。试想,原来 只能一个线程进入,现在却能同时16个写线程进入(写线程才需要锁定,而读线程几乎不受限制,之后会提到),并发性的提升是显而易见的。

ConcurrentHashMap的读取并发,因为在读取的大多数时候都没有用到锁定,所以读取操作几乎是完全的并发操作,而写操作锁定的粒度又非常细,比起之前又更加快速(这一点在桶更多时表现得更明显些)。只有在求size()containsValue()等操作时才需要锁定整个表。它们可能需要锁定整个 表而而不仅仅是某个段,这需要按顺序锁定所有段,操作完毕后,又按顺序释放所有段的锁(防止死锁)。

读是否要加锁,因为读写会发生冲突?ConcurrentHashMap完全允许多个读操作并发进行,读操作并不需要加锁。如果使 用传统的技术,如HashMap中的实现,如果允许可以在hash链的中间添加或删除元素,读操作不加锁将得到不一致的数据。 ConcurrentHashMap实现技术是保证HashEntry几乎是不可变的。HashEntry代表每个hash链中的一个节点,其结构如下所 示:

 static final class HashEntry<K,V> {   

final K key;   

final int hash;   

volatile V value;   

final HashEntry<K,V> next;   

 }  

可以看到HashEntry的一个特点,除了value以外,其他的几个变量都是final的,这样做是为了防止链表结构被破坏,出现ConcurrentModification的情况。为了确保读操作能够看到最新的值,将value设置成volatile,这避免了加锁。在当前的Java内存模型下,线程可以把变量保存在本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值的拷贝,造成数据的不一致。volatile关键字指示JVM,这个变量是不稳定的,每次使用它都到主存中进行读取。一般说来,多任务环境下各任务间共享的标志都应该加volatile修饰。Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。

--------------------------------------------------------------------

PS: 欢迎关注公众号"Devin说",会不定期更新Java相关技术知识。

--------------------------------------------------------------------

其他请参考:http://www.cnblogs.com/maxupeng/archive/2011/06/26/2090517.html

转载于:https://www.cnblogs.com/devinzhang/archive/2012/02/24/2366678.html

Java之currenHashMap相关推荐

  1. springboot实现SSE服务端主动向客户端推送数据,java服务端向客户端推送数据,kotlin模拟客户端向服务端推送数据

    SSE服务端推送 服务器向浏览器推送信息,除了 WebSocket,还有一种方法:Server-Sent Events(以下简称 SSE).本文介绍它的用法. 在很多业务场景中,会涉及到服务端向客户端 ...

  2. Java 获取当前时间之后的第一个周几,java获取当前日期的下一个周几

    Java 获取当前时间之后的第一个周几,java获取当前日期的下一个周几 //获得入参的日期 Calendar cd = Calendar.getInstance(); cd.setTime(date ...

  3. 在k8s中使用gradle构建java web项目镜像Dockerfile

    在k8s中使用gradle构建java web项目镜像Dockerfile FROM gradle:6-jdk8 AS build COPY --chown=gradle:gradle . /home ...

  4. Java | kotlin 手动注入bean,解决lateinit property loginService has not been initialized异常

    kotlin.UninitializedPropertyAccessException: lateinit property loginService has not been initialized ...

  5. SpringBoot项目使用nacos,kotlin使用nacos,java项目使用nacos,gradle项目使用nacos,maven项目使用nacos

    SpringBoot项目使用nacos kotlin demo见Gitte 一.引入依赖 提示:这里推荐使用2.2.3版本,springboot与nacos的依赖需要版本相同,否则会报错. maven ...

  6. OpenAPI使用(swagger3),Kotlin使用swagger3,Java使用swagger3,gradle、Maven使用swagger3

    OpenAPI使用(swagger3) demo见Gitte 一.背景及名词解释 OpenAPI是规范的正式名称.规范的开发工作于2015年启动,当时SmartBear(负责Swagger工具开发的公 ...

  7. Gradle错误提示:Java home supplied via ‘xxx.xxx.xxx‘ is invalid

    Gradle错误提示:Java home supplied via 'org.gradle.java.home' is invalid 描述:在使用idea采用gradle进行依赖的管理功能,当想切换 ...

  8. 查看Hotspot源码,查看java各个版本源码的网站,如何查看jdk源码

    java开发必知必会之看源码,而看源码的第一步则是找到源码

  9. java基本类型转换,随记

    java基本类型转换: double double 转 long double random = Math.round(Math.random()*10000); long l = new Doubl ...

最新文章

  1. CVPR 2021 | 中科大联合快手,提出人脸伪造检测新方法
  2. 我放弃了年薪200万的岗位,因为“复制粘贴”的技术活让人厌恶
  3. 华为、阿里员工跳槽至微软受抵制,微软当事人称:只是玩梗
  4. mysql 5.7.22 winx64_windows下mysql-5.7.22-winx64突然启动不了,报错Could not open log file
  5. JAVA中String类的intern()方法的作用
  6. PHP笔记-连接MySQL数据库及查询数据
  7. Javascript笔记:(实践篇)从jQuery插件技术说起-分析extend方法的源码(发现extend方法里有bug)(下篇)...
  8. Java 并发编程概念深入理解
  9. JAVA虚拟机垃圾回收机制和JAVA排错三剑客
  10. css flex布局
  11. 使用Clip Converter网站下载Yotube视频
  12. Java验证图片格式
  13. 贵港市计算机成绩查询,贵港驾驶证扣分查询
  14. 【游记】CQOI2021
  15. 适合CCCV操作的Fabric 1.4.6部署方案
  16. WEB页面登陆管理 H3C设备
  17. SuperMap三维专题之3dsMax数据——对接篇
  18. sql 中英文格式的时间转数字格式
  19. Computed property was assigned to but it has no setter问题随记
  20. 天池精准医疗大赛——人工智能辅助糖尿病遗传风险预测

热门文章

  1. 无论腾讯是自主开放还是被开放,我们都表示欢迎和支持
  2. Oracle啟動模式關閉模式
  3. docker详细介绍
  4. ROS系统 C++或Python实现订阅者Subscriber
  5. 【SSM框架系列】Spring IoC(控制反转) DI(依赖注入)注解开发
  6. deep learning:RBM公式推导+源码 ----- C++
  7. 半斤八两中级破解 (四) TCP_UDP协议转向本地验证
  8. 34.16.159(zz)
  9. fhqtreap的学习笔记
  10. Centos 7下搭建WordPress