ConcurrentHashMap 1.8为什么要使用CAS+Synchronized取代Segment+ReentrantLock
大家应该都知道ConcurrentHashMap在1.8的时候有了很大的改动,当然,我这里要说的改动不是指链表长度大于8就转为红黑树这种常识,我要说的是ConcurrentHashMap在1.8为什么用CAS+Synchronized取代Segment+ReentrantLock了
首先,我假设你对CAS,Synchronized,ReentrantLock这些知识很了解,并且知道AQS,自旋锁,偏向锁,轻量级锁,重量级锁这些知识,也知道Synchronized和ReentrantLock在唤醒被挂起线程竞争的时候有什么区别
首先我们说下1.8以前的ConcurrentHashMap是怎么保证线程并发的,首先在初始化ConcurrentHashMap的时候,会初始化一个Segment数组,容量为16,而每个Segment呢,都继承了ReentrantLock类,也就是说每个Segment类本身就是一个锁,之后Segment内部又有一个table数组,而每个table数组里的索引数据呢,又对应着一个Node链表.
那么这样的好处是什么呢?我先从老版本的添加流程说起吧,由于电脑里没有JDK1.7及以下的版本我没法给你看代码,所以使用文字描述的方式,首先,当我们使用put方法的时候,是对我们的key进行hash拿到一个整型,然后将整型对16取模,拿到对应的Segment,之后调用Segment的put方法,然后上锁,请注意,这里lock()的时候其实是this.lock(),也就是说,每个Segment的锁是分开的
其中一个上锁不会影响另一个,此时也就代表了我可以有十六个线程进来,而ReentrantLock上锁的时候如果只有一个线程进来,是不会有线程挂起的操作的,也就是说只需要在AQS里使用CAS改变一个state的值为1,此时就能对代码进行操作,这样一来,我们等于将并发量/16了.
好,说完了老版本的ConcurrentHashMap,我们再说说新版本的,请看下面的图:

请注意Synchronized上锁的对象,请记住,Synchronized是靠对象的对象头和此对象对应的monitor来保证上锁的,也就是对象头里的重量级锁标志指向了monitor,而monitor呢,内部则保存了一个当前线程,也就是抢到了锁的线程.
那么这里的这个f是什么呢?它是Node链表里的每一个Node,也就是说,Synchronized是将每一个Node对象作为了一个锁,这样做的好处是什么呢?将锁细化了,也就是说,除非两个线程同时操作一个Node,注意,是一个Node而不是一个Node链表哦,那么才会争抢同一把锁.
如果使用ReentrantLock其实也可以将锁细化成这样的,只要让Node类继承ReentrantLock就行了,这样的话调用f.lock()就能做到和Synchronized(f)同样的效果,但为什么不这样做呢?
请大家试想一下,锁已经被细化到这种程度了,那么出现并发争抢的可能性还高吗?还有就是,哪怕出现争抢了,只要线程可以在30到50次自旋里拿到锁,那么Synchronized就不会升级为重量级锁,而等待的线程也就不用被挂起,我们也就少了挂起和唤醒这个上下文切换的过程开销.
但如果是ReentrantLock呢?它则只有在线程没有抢到锁,然后新建Node节点后再尝试一次而已,不会自旋,而是直接被挂起,这样一来,我们就很容易会多出线程上下文开销的代价.当然,你也可以使用tryLock(),但是这样又出现了一个问题,你怎么知道tryLock的时间呢?在时间范围里还好,假如超过了呢?
所以,在锁被细化到如此程度上,使用Synchronized是最好的选择了.这里再补充一句,Synchronized和ReentrantLock他们的开销差距是在释放锁时唤醒线程的数量,Synchronized是唤醒锁池里所有的线程+刚好来访问的线程,而ReentrantLock则是当前线程后进来的第一个线程+刚好来访问的线程.
如果是线程并发量不大的情况下,那么Synchronized因为自旋锁,偏向锁,轻量级锁的原因,不用将等待线程挂起,偏向锁甚至不用自旋,所以在这种情况下要比ReentrantLock高效
ConcurrentHashMap 1.8为什么要使用CAS+Synchronized取代Segment+ReentrantLock的更多相关文章
- java8的ConcurrentHashMap为何放弃分段锁,为什么要使用CAS+Synchronized取代Segment+ReentrantLock
原文地址:https://cloud.tencent.com/developer/article/1509556 推荐一篇 ConcurrentHashMap 和 HashMap 写的比较的的文章 j ...
- synchronized和锁(ReentrantLock) 区别
synchronized和锁(ReentrantLock) 区别 java的两种同步方式, Synchronized与ReentrantLock的区别 并发(一):理解可重入锁 可重入锁和不可重入锁 ...
- Android进阶——多线程系列之wait、notify、sleep、join、yield、synchronized关键字、ReentrantLock锁
多线程一直是初学者最困惑的地方,每次看到一篇文章,觉得很有难度,就马上叉掉,不看了,我以前也是这样过来的.后来,我发现这样的态度不行,知难而退,永远进步不了.于是,我狠下心来看完别人的博客,尽管很难但 ...
- java synchronized和(ReentrantLock)区别
原文:http://blog.csdn.net/zheng548/article/details/54426947 区别一:API层面 syschronized使用 synchronized即可修饰方 ...
- Java并发容器--ConcurrentHashMap
引子 1.不安全:大家都知道HashMap不是线程安全的,在多线程环境下,对HashMap进行put操作会导致死循环.是因为多线程会导致Entry链表形成环形数据结构,这样Entry的next节点将永 ...
- (一)juc线程高级特性——volatile / CAS算法 / ConcurrentHashMap
1. volatile 关键字与内存可见性 原文地址: https://www.cnblogs.com/zjfjava/category/979088.html 内存可见性(Memory Visibi ...
- HashMap,ConcurrentHashMap原理。Collection(list,set,map集合区别)。和CAS
collection里面有什么子类?(list和set是实现了collection接口的.) List: 1.可以允许重复的对象(可重复,有序集合).2.可以插入多个null元素.3.常用的实现类有 ...
- 并发系列2:Java并发的基石,volatile关键字、synchronized关键字、乐观锁CAS操作
由并发大师Doug Lea操刀的并发包Concurrent是并发编程的重要包,而并发包的基石又是volatile关键字.synchronized关键字.乐观锁CAS操作这些基础.因此了解他们的原理对我 ...
- Java并发(4)- synchronized与CAS
引言 上一篇文章中我们说过,volatile通过lock指令保证了可见性.有序性以及"部分"原子性.但在大部分并发问题中,都需要保证操作的原子性,volatile并不具有该功能,这 ...
随机推荐
- d3.js--01
D3 的全称是(Data-Driven Documents),顾名思义可以知道是一个被数据驱动的文档.听名字有点抽象,说简单一点,其实就是一个 JavaScript 的函数库,使用它主要是用来做数据可 ...
- session 关于localhost和本地IP地址 不共享问题
打比方, 一个请求 localhost:8080/test/test ,一个本地Ip(172.1.1.1:8080/test/test) 1.请求localhost方式 HttpSession s ...
- js控制时间显示格式
Date.prototype.Format = function (fmt) { //author: meizz var o = { "M+": this.g ...
- pymysql模块操作数据库及连接报错解决方法
import pymysql sql = "select host,user,password from user" #想要执行的MySQL语句 #sql = 'create da ...
- centos7上mysql8.0rpm方式安装
首先是下载图解 1.首先卸载centos7中自带的mariadb rpm -qa|grep mariadb //查询出来已安装的mariadb rpm -e --nodeps 文件名 //卸载mari ...
- 动态规划:HDU2571-命运
解题心得: 1.其实是一个简单的动态规划加上贪心的思想,思路简单,只需要求每一步的最大值就可以了,但是要注意读懂题. 2.走的规则:从左上角开始走,达到右下角,只能向右走一步,或者向下走一步,或者走列 ...
- (PowerDesigner&Sqlite)PD中设计完表后,将其导入数据库中
本人连接过SQLServer跟SQLite Ⅰ.SQLServer,百度,转一下:http://jingyan.baidu.com/article/7f766daf465e9c4101e1d0d5.h ...
- Cuba studio框架中使用thymeteaf模板时中文乱码
最近公司换了Cuba这个orm框架,框架中使用了thymeteaf模板技术,发现在html中解析汉字一直是乱码的存在 一直以为是tomcat的问题但是tomcat的server.xml,项目中的web ...
- 图文详解安装PHP运行环境
一.什么是PHP运行环境 能够理解人与计算机交流时语言软件,通常指解释PHP编程语言的软件. 例如: PHP(代码) 需要PHP超文本预编译器(软件). Java需要JVM虚拟机 二.安装PHP运行环 ...
- 设计模式之第6章-迭代器模式(Java实现)
设计模式之第6章-迭代器模式(Java实现) “我已经过时了,就不要讲了吧,现在java自带有迭代器,还有什么好讲的呢?”“虽然已经有了,但是具体细节呢?知道实现机理岂不美哉?”“好吧好吧.”(迭代器 ...