【Java并发编程】23、ConcurrentHashMap原理分析(1.7和1.8版本对比)
jdk 1.8版本
ConcurrentHashMap在1.8中的实现,相比于1.7的版本基本上全部都变掉了。首先,取消了Segment分段锁的数据结构,取而代之的是数组+链表(红黑树)的结构。而对于锁的粒度,调整为对每个数组元素加锁(Node)。
put的步骤大致如下:
- 参数校验。
- 若table[]未创建,则初始化。table的初始化和扩容采用CAS无锁设计,通过状态 sizeCtl 来控制线程的并发操作:U.compareAndSwapInt(this, SIZECTL, sc, -1)
- 当table[i]后面无节点时,直接创建Node(无锁操作)。也是通过CAS实现:return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v);
- 如果当前正在扩容,则帮助扩容并返回最新table[]。
- 然后在链表或者红黑树中追加节点。此过程通过synchronized (f) 锁定当前node实现线程安全
- 如果是链表,遍历链表,发现相同key则替换旧值,没有发现相同key则添加到链表的末尾
- 如果是红黑树,执行红黑树的插入代码。执行完毕,synchronized (f) 锁退出
- 最后还回去判断是否到达阀值,如到达变为红黑树结构。使用方法:treeifyBin(tab, i);
- treeifyBin(tab, i)方法执行过程:如果容量小于64,直接扩容,不需要转变成红黑树。否则,对链表的头结点加synchronized 锁,以他为根节点构造红黑树
get()方法没有加锁操作,步骤如下:
- 首先定位到table[]中的i。
- 若table[i]存在,则继续查找。
- 首先比较链表头部,如果是则返回。
- 然后如果为红黑树,查找树。
- 如果不是红黑树,循环链表查找。
参考网上的详细说明资料如下:
【Java并发编程】23、ConcurrentHashMap原理分析(1.7和1.8版本对比)的更多相关文章
- java并发系列(七)-----ConcurrentHashMap原理分析(JDK1.8)
JDK1.8的实现已经摒弃了Segment的概念,而是直接用Node数组+链表+红黑树的数据结构来实现,并发控制使用Synchronized和CAS来操作,整个看起来就像是优化过且线程安全的HashM ...
- Java并发编程底层实现原理 - volatile
Java语言规范第三版中对volatile的定义如下: Java编程语言允许线程访问共享变量,为了确保共享变量能被准确和一致性的更新,线程应该确保通过排他锁 单独获得这个变量. volatile有时候 ...
- Java并发编程-AbstractQueuedSynchronizer源码分析
简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...
- Java并发编程-Unsafe实现原理与Unsafe应用解析
前言 Unsafe是位于sun.misc包下的一个类,主要提供一些用于执行低级别.不安全操作的方法,如直接访问系统内存资源.自主管理内存资源等,这些方法在提升Java运行效率.增强Java语言底层资源 ...
- Java并发编程-ReentrantLock源码分析
一.前言 在分析了 AbstractQueuedSynchronier 源码后,接着分析ReentrantLock源码,其实在 AbstractQueuedSynchronizer 的分析中,已经提到 ...
- Java并发编程 ReentrantLock 源码分析
ReentrantLock 一个可重入的互斥锁 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大. 这个类主要基于AQS(Abst ...
- Java并发编程 LockSupport源码分析
这个类比较简单,是一个静态类,不需要实例化直接使用,底层是通过java未开源的Unsafe直接调用底层操作系统来完成对线程的阻塞. package java.util.concurrent.locks ...
- java并发编程系列原理篇--JDK中的通信工具类Semaphore
前言 java多线程之间进行通信时,JDK主要提供了以下几种通信工具类.主要有Semaphore.CountDownLatch.CyclicBarrier.exchanger.Phaser这几个通讯类 ...
- Java并发编程笔记之ConcurrentHashMap原理探究
在多线程环境下,使用HashMap进行put操作时存在丢失数据的情况,为了避免这种bug的隐患,强烈建议使用ConcurrentHashMap代替HashMap. HashTable是一个线程安全的类 ...
- Java并发编程(七)ConcurrentLinkedQueue的实现原理和源码分析
相关文章 Java并发编程(一)线程定义.状态和属性 Java并发编程(二)同步 Java并发编程(三)volatile域 Java并发编程(四)Java内存模型 Java并发编程(五)Concurr ...
随机推荐
- 架构(二)Maven安装以及Nexus配置
一 Maven安装配置 1.1 下载 http://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.5.4/binaries/apache-ma ...
- Chapter 8 The Simplest Plug-in Solution
This chapter introduces the simplest plug-in solution that are applicable to the four major componen ...
- 剑指offer面试题23:从上到下打印二叉树(树的层序遍历)
题目:从上往下打印出二叉树的每个节点,同一层的结点按照从左往右的顺序打印. 解题思路:二叉树的层序遍历,在打印一个节点的时候,要把他的子节点保存起来打印第一层要把第二层的节点保存起来, 打印第二层要把 ...
- 《响应式Web设计实践》学习笔记
原书: 响应式Web设计实践 目录: 第2章 流动布局 1. 布局选项 2. 字体大小 3. 网格布局 4. 混合固定宽度和流动宽度 第3章 媒介查询 1. 视口 2. 媒介查询结构 3. 内嵌样式与 ...
- Codeforces Round #554 (Div. 2) 1152A - Neko Finds Grapes
学了这么久,来打一次CF看看自己学的怎么样吧 too young too simple 1152A - Neko Finds Grapes 题目链接:"https://codeforces. ...
- ubuntu18.04安装redis
首先更新源 sudo apt-get update 安装命令: sudo apt-get install redis-server 查看tcp 连接 netstat -ap | grep 6379 ...
- Conflict with dependency 'com.android.support:support-annotations' in project ':xxx'. Resolved versions for app (25.4.0) and test app (27.1.1) differ 问题解决
Conflict with dependency 'com.android.support:support-annotations' in project ':xxx'. Resolved versi ...
- puppetdb搭建
puppetdb搭建 在agent端跑puppet agent -t 正常的情况下,安装puppetdb 部署postgresql数据库 部署puppetdb 建立puppetserver与puppe ...
- oo第二单元的自白
电梯第一次作业 第一次电梯较为简单,主要目的在于初步接触多线程,可以实现一些简单的操作. 在本次作业中,为了更好的了解多线程,我也阅读了一些代码,并据此仿写完成了第一次作业. 根据生产者和消费者的模式 ...
- 深入分析Java I/O的工作机制 (三)网络I/O的工作机制 很详细
3.网络I/O的工作机制 前言:数据从一台主机(服务端)发送到网络中的另一台主机(客户端)需要经过很多步骤:首先需要有相互沟通的意向.其次要有能够沟通的物理渠道(物理链路):是通过电话,还是直接面对面 ...