【专栏集合】ConcurrentHashMap
锁
1.8 之前:
使用Segment(分段锁,它继承了ReentrantLock ReentrantLock 是AQS(抽象队列同步框架) 的独占锁模式)
ReentrantLock实现模式
一个数组分为多个段落,然后每个段落对应一个资源state(int类型 初始为0加锁 +1 释放锁-1 等于0则代表没有被占用),线程并发的时候每个线程会封装成一个node节点进入aqs阻塞队列 队列首节点判断state是否为0 ,为0则+1执行难此资源,如果是独占模式则是等首节点执行完后唤醒后续节点进行获取资源操作;
共享模式如下:不是首节点的会判断自己node.pre是否为首节点如果是则casAndSwap 资源 如果node.pre不是首节点则自旋;
缺点:
1、分段后加锁不连续会导致碎片化,内存资源浪费
2、对象创建后分段数量不变,当进行扩容时,每段大小增加导致锁的粒度增大导致并发能力减弱
3、使用ReentrantLock则需要节点继承AQS来获得同步支持,增加内存开销
1.8 之后:
使用synchronized+cas那么synchronized和cas分别用在了什么地方呢?
synchronized用在锁住数组桶内链表头节点上
cas用在初始化桶中第一个元素的时候会进行cas
数据结构
1.8 之前:
数组+链表
1.8 之后:
数组+链表+红黑树
当数组长度大于60的时候链表长度大于8的时候会变为红黑树
扩容
1.8 之前:
数组默认16 ;当存入数据大小大于16*负载因子(0.75)=12的时候会进行扩容,扩容俩倍,之所以是2倍是因为可以让hashcode更均匀分散
1.8 之后:
数组默认16 ;当存入数据大小大于16*负载因子(0.75)=12的时候会进行扩容,扩容俩倍,之所以是2倍是因为可以让hashcode更均匀分散
链表插入方式
1.8 之前:头插法
并发情况会导致环形链表:
线程一:读取到当前的hashmap情况,在准备扩容时,线程二介入
线程二:读取hashmap,进行扩容
线程一:继续执行
简单来说就是头插法情况下 a>b数组在 1线程进行扩容还没有开始此时cpu调度到了 2线程 然后取值到新数组变成了a先到后b到然后因为头插法 将b插入到了a前面 此时变为b>a 然后 cpu继续调度 1线程 发现b>a 然后自己内存的事a>b 然后就变成了b>a>b
jdk 1.8之后
使用尾插法不会出现环形链表
【专栏集合】ConcurrentHashMap相关推荐
- Java集合 - ConcurrentHashMap
介绍 ConcurrentHashMap 技术是为了解决问题而生的,ConcurrentHashMap 解决了多个线程同时操作一个 HashMap 时,可能出现的内部问题.当多个线程同时操作一个 Ha ...
- javacurrentmap_Java集合---ConcurrentHashMap原理分析
final Segment segmentFor(inthash) { return segments[(hash >>> segmentShift) &segmentMas ...
- lisp钢管_技术专栏集合管道模式(上)
译者按: 近来想深入了解下 Java 流底层的实现机制,于是搜索各种资源,最后发现 Martin Fowler 发表的一篇关于集合管道模式的一篇文章,有幸得以拜读,关于集合管道有其独到的见解,看过之后 ...
- [JDK1.6] JAVA集合 ConcurrentHashMap源码浅析
文章目录 一 简介: ConcurrentHashMap 存储数据的结构与架构图 ConcurrentHashMap 的字段与常量 构造方法 存储数据 put(K, V) 获取数据 get(Objec ...
- [集合]ConcurrentHashMap的源码分析
前言: 强推:一文读懂HashMap 这感觉讲的HashMap很明白. 1. 多线程环境下面,HashMap和Hashtable会怎么样? 1.1 HashMap 因为put会调用: // 新增Ent ...
- java 集合读写同步_JAVA多线程学习十六 - 同步集合类的应用
1.引言 在多线程的环境中,如果想要使用容器类,就需要注意所使用的容器类是否是线程安全的.在最早开始,人们一般都在使用同步容器(Vector,HashTable),其基本的原理,就是针对容器的每一个操 ...
- Java ConcurrentHashMap 最佳实践
2019独角兽企业重金招聘Python工程师标准>>> Java ConcurrentHashMap 最佳实践 博客分类: java 相对于HashMap,ConcurrentHas ...
- Java面试含答案(最全版)
1.面向对象和面向过程的区别 面向过程 优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机.嵌入式开发.Linux/Unix等一般采用面向过程开发,性能是最重要的因素 ...
- Java方向如何准备BAT技术面试答案(汇总版)
转自:http://www.jianshu.com/p/1f1d3193d9e3 原文链接:Java方向如何准备BAT技术面试答案(汇总版) 这个主题的内容之前分三个篇幅分享过,导致网络上传播的比较分 ...
最新文章
- 2019年最新10份开源Java精选资料
- java中Collections的接口及类层次图
- npm包全局安装和局部安装,执行包命令有什么不同?
- C#中怎样获取默认配置文件App.config中配置的键值对内容
- IT大佬廖雪峰带你玩转Python数据分析(内附资源)
- ckeditor_学习(2) 功能概览
- LInux 阿里云系统遇到挖矿程序
- Java之HashMap、Hashtable、LinkedHashMap、TreeMap、ConcurrentHashMap简单的区别
- 【渝粤教育】 国家开放大学2020年春季 1129土木工程力学(本) 参考试题
- csgo被会话踢出什么鬼_【解决方案】“CSGO游戏—断开连接,VAC无法验证会话”问题解决方案...
- 光纤 matlab,matlab – 均衡光纤通道的最小均方
- Linux su和sudo命令的区别,并获得root权限
- RPM 的介绍和应用
- linux shell 中的冒号,在bash中使用:-(冒号)
- 把Unity的jdk环境添加到环境变量
- UniBeast:在任何支持基于英特尔处理器的PC上安装OS X优胜美地
- 博士申请 | 皇家墨尔本理工大学鲍芝峰教授招收数据挖掘方向全奖博士生
- HTC Vive Unity 教程
- 学大伟业:化学竞赛学习规划与推荐书目
- 0926 - 微商的动力