首页 > 其他分享 >谈谈ConcurrentHashMap是如何保证线程安全的?

谈谈ConcurrentHashMap是如何保证线程安全的?

时间:2023-03-18 12:11:12浏览次数:56  
标签:JDK1.8 ConcurrentHashMap 粒度 链表 谈谈 线程 Segment 节点

jdk1.7中是采用Segment + HashEntry + ReentrantLock的方式进行实现的,而1.8中放弃了Segment臃肿的设计,取而代之的是采用Node + CAS + Synchronized来保证并发安全进行实现。

  • JDK1.8的实现降低锁的粒度,JDK1.7版本锁的粒度是基于Segment的,包含多个HashEntry,而JDK1.8锁的粒度就是HashEntry(首节点)
  • JDK1.8版本的数据结构变得更加简单,使得操作也更加清晰流畅,因为已经使用synchronized来进行同步,所以不需要分段锁的概念,也就不需要Segment这种数据结构了,由于粒度的降低,实现的复杂度也增加了
  • JDK1.8使用红黑树来优化链表,基于长度很长的链表的遍历是一个很漫长的过程,而红黑树的遍历效率是很快的,代替一定阈值的链表,这样形成一个最佳拍档

JDK1.8的get操作

  • 首先计算hash值,定位到该table索引位置,如果是首节点符合就返回
  • 如果遇到扩容的时候,会调用标志正在扩容节点ForwardingNode的find方法,查找该节点,匹配就返回
  • 以上都不符合的话,就往下遍历节点,匹配就返回,否则最后就返回null

为什么get操作不需要加锁

get操作可以无锁是由于Node的元素val和指针next是用volatile修饰的,在多线程环境下线程A修改结点的val或者新增节点的时候是对线程B可见的,数组用volatile修饰没有关系。

数组用volatile修饰主要是保证在数组扩容的时候保证可见性。

 

参考:

标签:JDK1.8,ConcurrentHashMap,粒度,链表,谈谈,线程,Segment,节点
From: https://www.cnblogs.com/xfeiyun/p/17229694.html

相关文章

  • 守护线程
    packageedu.wtbu;//测试守护线程//上帝守护你publicclassDemo07{publicstaticvoidmain(String[]args){Godgod=newGod();Youyou=new......
  • 线程的优先级
    packageedu.wtbu;//测试线程的优先级publicclassDemo06{publicstaticvoidmain(String[]args){//Thread.MAX_PRIORITY=10//Thread.Min_PRIOR......
  • 线程停止
    packageedu.wtbu;publicclassDemo01implementsRunnable{//1.设置一个标识位privatebooleanflag=true;@Overridepublicvoidrun(){inti......
  • 说一下线程池内部工作原理(ThreadPoolExecutor)
    ThreadPoolExecutor构造方法的参数corePoolSize:线程池的核心线程数,说白了就是,即便是线程池里没有任何任务,也会有corePoolSize个线程在候着等任务。maximumPoolSize:最大......
  • 进程和线程
    进程、线程1进程与线程的关系和区别什么是进程定义:进程是一个具有一定独立功能的程序在一个数据集合上依次动态执行的过程。进程是一个正在执行的程序的实例,包括程序......
  • 线程执行顺序
    线程执行顺序在做面试题的时候,发现有关线程执行顺序的一个常见考题:(纯纯考研审题)packagelink;publicclassTest{publicstaticvoidmain(String[]args){......
  • 谈谈为什么要拆分数据库?有哪些方法?
    为什么要拆分数据库?数据库负载和数据量大拆分数据库是有讲究的,必须:先水平切分,然后垂直切分。什么是垂直切分?垂直切分是根据业务来拆分数据库,同一类业务的数据表拆分到......
  • C# 多线程task
    C#多线程task1.异步和多线程的区别?没什么太大区别。异步是目的,使用多线程实现。想想AJAX异步加载,不就是不想让浏览器界面卡住嘛,所以在程序中对于某些单独的操作,比如写......
  • 分别谈谈联合索引生效和失效的条件
    联合索引失效的条件联合索引又叫复合索引。两个或更多个列上的索引被称作复合索引。对于复合索引:Mysql从左到右使用索引中的字段,一个查询可以只使用索引中的一部分,但只能......
  • 请你谈谈关于IO同步、异步、阻塞、非阻塞的区别
    对于一个networkIO(这里我们以read举例),它会涉及到两个系统对象,一个是调用这个IO的process(orthread),另一个就是系统内核(kernel)。当一个read操作发生时,它会经历两个......