JAVA线程安全Map解析
JAVA线程安全Map解析
- HashTable
- 结构
- 线程安全的实现
- Collections.synchronizedMap
- 线程安全的实现
- ConcurrentHashMap
- 线程安全的实现
- ConcurrentHashMap的结构
- 线程安全的具体实现
- 经过hash计算,指定下标没有数据
- 经过hash计算,发生Hash碰撞
- 代码实现
- JAVA集合目录
HashTable
结构
采用的是数组加上链表组成,链表部分插入为尾插。
线程安全的实现
对所有的操作方法进行加锁。
public synchronized V put(K key, V value) {// Make sure the value is not nullif (value == null) {throw new NullPointerException();}// Makes sure the key is not already in the hashtable.Entry<?,?> tab[] = table;int hash = key.hashCode();int index = (hash & 0x7FFFFFFF) % tab.length;@SuppressWarnings("unchecked")Entry<K,V> entry = (Entry<K,V>)tab[index];for(; entry != null ; entry = entry.next) {if ((entry.hash == hash) && entry.key.equals(key)) {V old = entry.value;entry.value = value;return old;}}addEntry(hash, key, value, index);return null;}public synchronized V remove(Object key) {Entry<?,?> tab[] = table;int hash = key.hashCode();int index = (hash & 0x7FFFFFFF) % tab.length;@SuppressWarnings("unchecked")Entry<K,V> e = (Entry<K,V>)tab[index];for(Entry<K,V> prev = null ; e != null ; prev = e, e = e.next) {if ((e.hash == hash) && e.key.equals(key)) {modCount++;if (prev != null) {prev.next = e.next;} else {tab[index] = e.next;}count--;V oldValue = e.value;e.value = null;return oldValue;}}return null;}
Collections.synchronizedMap
线程安全的实现
使用java.util.Collections.SynchronizedMap代理类,把线程不安全的Map代理成线程安全的Map,在所有的方法上添加同步锁实现。
ConcurrentHashMap
线程安全的实现
- CAS操作
- 局部加锁
ConcurrentHashMap的结构
ConcurrentHashMap的结构由数组、链表、红黑树组成。
线程安全的具体实现
经过hash计算,指定下标没有数据
通过CAS替换。
经过hash计算,发生Hash碰撞
对该节点链表或者是红黑树的头节点进行加锁。
代码实现
final V putVal(K key, V value, boolean onlyIfAbsent) {if (key == null || value == null) throw new NullPointerException();int hash = spread(key.hashCode());int binCount = 0;for (Node<K,V>[] tab = table;;) {Node<K,V> f; int n, i, fh;if (tab == null || (n = tab.length) == 0)tab = initTable();// 如果原有的数组为空,直接使用cas进行替换即可else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {if (casTabAt(tab, i, null,new Node<K,V>(hash, key, value, null)))break; // no lock when adding to empty bin}// 如果正在扩容、多线程帮忙扩容else if ((fh = f.hash) == MOVED)tab = helpTransfer(tab, f);else {V oldVal = null;// 对头结点进行加锁synchronized (f) {if (tabAt(tab, i) == f) {if (fh >= 0) {binCount = 1;for (Node<K,V> e = f;; ++binCount) {K ek;if (e.hash == hash &&((ek = e.key) == key ||(ek != null && key.equals(ek)))) {oldVal = e.val;if (!onlyIfAbsent)e.val = value;break;}Node<K,V> pred = e;if ((e = e.next) == null) {pred.next = new Node<K,V>(hash, key,value, null);break;}}}else if (f instanceof TreeBin) {Node<K,V> p;binCount = 2;if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,value)) != null) {oldVal = p.val;if (!onlyIfAbsent)p.val = value;}}}}if (binCount != 0) {// 列百年的数据长度大于等于8、转换为红黑树if (binCount >= TREEIFY_THRESHOLD)treeifyBin(tab, i);if (oldVal != null)return oldVal;break;}}}addCount(1L, binCount);return null;}
JAVA集合目录
java集合目录
JAVA线程安全Map解析相关推荐
- 四种Java线程池用法解析
四种Java线程池用法解析 本文为大家分析四种Java线程池用法,供大家参考,具体内容如下 http://www.jb51.net/article/81843.htm 1.new Thread的弊端 ...
- Java线程状态完全解析教程
简介 Java线程有6种状态,分别是NEW.RUNNABLE.BLOCKED.WAITING.TIMED_WAITING.TERMINATED.本文讲解线程状态变化的流程以及用代码演示通过调用哪些方法 ...
- 面试题:四种Java线程池用法解析 !=!=未看
1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? 1 2 3 4 5 6 7 8 new Thread(new Runnable() { @Override ...
- Java开发中Netty线程模型原理解析!
Java开发中Netty线程模型原理解析,Netty是Java领域有名的开源网络库具有高性能和高扩展性的特点,很多流行的框架都是基于它来构建.Netty 线程模型不是一成不变的,取决于用户的启动参数配 ...
- java+线程安全的hash,多线程下HashMap安全问题-ConcurrentHashMap解析
Java1.5 引入了 java.util.concurrent 包,其中 Collection 类的实现允许在运行过程中修改集合对象.实际上, Java 的集合框架是[迭代器设计模式]的一个很好的实 ...
- Java 调用Google Map Api解析地址,解析经纬度实例
Java 调用Google Map Api解析地址,解析经纬度实例 使用google地图的反向地址解析功能,提供一个经纬度得到对应地址,或者给出模糊地址,得到经纬度,放在java后台代码中处理,这个使 ...
- Java Executor源码解析(3)—ThreadPoolExecutor线程池execute核心方法源码【一万字】
基于JDK1.8详细介绍了ThreadPoolExecutor线程池的execute方法源码! 上一篇文章中,我们介绍了:Java Executor源码解析(2)-ThreadPoolExecutor ...
- java任务流程_死磕 java线程系列之线程池深入解析——普通任务执行流程
(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本. 注:线程池源码部分如无特殊说明均指ThreadPoolExecutor类. 简介 前面我们一起学习了Java中 ...
- Java线程池源码解析及高质量代码案例
引言 本文为Java高级编程中的一些知识总结,其中第一章对Jdk 1.7.0_25中的多线程架构中的线程池ThreadPoolExecutor源码进行架构原理介绍以及源码解析.第二章则分析了几个违反J ...
最新文章
- 交互式讲解傅里叶变换
- table布局注意点
- 理解Java动态代理(1)—找我还钱?我出钱要你的命
- python绘制散点图-Python:matplotlib绘制散点图
- slf4j 如何返回堆栈_重学JS系列 - JS 调用堆栈
- linux 64 nc,linux 命令之nc
- spark-jar冲突解决方案
- HTML、CSS规范
- 图论 —— 图的连通性 —— Tarjan 缩点
- sed的模式匹配用法探讨
- 洛谷——P1046 [NOIP2005 普及组] 陶陶摘苹果
- Win10 镜像安装到新固态硬盘两法
- git cherry-pick 的使用
- php postgresql 参数,从postgresql函数参数中检索php数组键和值以进行数据库更新
- 豆瓣250排行榜算法
- 京东EB级全域大数据平台的演进与治理历程
- html怎样做修改密码的网页,HTML登录界面 html登录界面设置账号密码
- kubernetes 从入门到实践
- Matlab散点图进阶——矩阵气泡图
- 永远不要在MySQL中使用UTF-8
热门文章
- 用ATL创建COM组件及实例讲解
- 微信小程序-会议OA项目03
- list列表 python
- android 怎么导入项目,Android Studio怎么导入项目?
- 一、Kubernetes (k8s) 是什么, 有什么用?
- php取指定时间毫秒数,PHP取毫秒时间戳 microtime()
- Java咖啡馆(5)——Java语言基础
- 【无标题】尤破金12.1黄金还会跌吗?黄金原油行情趋势分析及晚间走势预测
- LeafletJS 简单使用3(超图使用问题解决) - 继1/2出现的问题及解决(超图更换地图地址之后瓦片空白问题解决)
- 用Python画一个小猪佩奇