java并发编程实战wwj----------第三阶段-------------ConcurrentHashMap----------------72
阻塞队列:多个线程操作的队列。
JDK7:分成若干哥Segments。
是一个key和value数组。
原理:https://blog.csdn.net/it_dx/article/details/77941538
我们看get的方法。
get:
public V get(Object key) {Segment<K,V> s; HashEntry<K,V>[] tab;//根据key的值计算hash值int h = hash(key);//获得segment的index long u = (((h >>> segmentShift) & segmentMask) << SSHIFT) + SBASE;//保证拿到的是最新的if ((s = (Segment<K,V>)UNSAFE.getObjectVolatile(segments, u)) != null && //通过hash值定位segment中对应的HashEntry 遍历HashEntry,
如果key存在,返回key对应的value 如果不存在则返回null(tab = s.table) != null) {for (HashEntry<K,V> e = (HashEntry<K,V>) UNSAFE.getObjectVolatile(tab, ((long)(((tab.length - 1) & h)) << TSHIFT) + TBASE);e != null; e = e.next) {K k;if ((k = e.key) == key || (e.hash == h && key.equals(k)))return e.value;}}return null;}
put:
public V put(K key, V value) {Segment<K,V> s;//键和值都不能为空if (value == null)throw new NullPointerException();//计算key的hash值int hash = hash(key);//获得key所属的segemngtint j = (hash >>> segmentShift) & segmentMask;if ((s = (Segment<K,V>)UNSAFE.getObject (segments, (j << SSHIFT) + SBASE)) == null)//初试化segment(懒加载模式)s = ensureSegment(j);return s.put(key, hash, value, false);}
final V put(K key, int hash, V value, boolean onlyIfAbsent) {
//获取锁,保证线程安全HashEntry<K,V> node = tryLock() ? null :scanAndLockForPut(key, hash, value);V oldValue;try {HashEntry<K,V>[] tab = table;int index = (tab.length - 1) & hash;HashEntry<K,V> first = entryAt(tab, index); //定位到具体的HashEntryfor (HashEntry<K,V> e = first;;) { //3if (e != null) {K k;if ((k = e.key) == key ||(e.hash == hash && key.equals(k))) {oldValue = e.value;//覆盖旧值if (!onlyIfAbsent) {e.value = value;++modCount;}break;}e = e.next;}else {if (node != null)node.setNext(first);elsenode = new HashEntry<K,V>(hash, key, value, first);int c = count + 1;if (c > threshold && tab.length < MAXIMUM_CAPACITY)rehash(node);elsesetEntryAt(tab, index, node);++modCount;count = c;oldValue = null;break;}}} finally {//释放锁unlock();}//返回旧值return oldValue;}
size:
public int size() {final Segment<K,V>[] segments = this.segments;int size;boolean overflow; long sum; long last = 0L; int retries = -1; try {for (;;) {//RETRIES_BEFORE_LOCK为不变常量2 尝试两次不锁住Segment的方式来统计每个Segment的大小,如果在统计的过程中Segment的count发生变化,这时候再加锁统计Segment的countif (retries++ == RETRIES_BEFORE_LOCK) { //加锁for (int j = 0; j < segments.length; ++j)ensureSegment(j).lock(); }sum = 0L;size = 0;overflow = false;for (int j = 0; j < segments.length; ++j) {Segment<K,V> seg = segmentAt(segments, j);if (seg != null) {sum += seg.modCount; //2int c = seg.count;if (c < 0 || (size += c) < 0)overflow = true;}}if (sum == last)break;last = sum;}} finally {if (retries > RETRIES_BEFORE_LOCK) {for (int j = 0; j < segments.length; ++j)segmentAt(segments, j).unlock();}}return overflow ? Integer.MAX_VALUE : size;}
我总结一个重要的知识点:
通过key的hash再位移值获得key所属的segment,segment.put中通过key的hash值再(tab.length - 1) & hash获取index定位到是哪个hashEntry。遍历hashEntry。
判断hashEntry是不是存在这个值:
1.通过key,1不成立的话就是2.节点的hash==key的hash&&节点的key去equals输入的key。
put的话就是如果通过key的hash再(tab.length - 1) & hash去定位HashEntry有值了,就加个链表节点,节点的key就是元素的hash值,并且节点的key要equals元素的key。
----------------------------------
java并发编程实战wwj----------第三阶段-------------ConcurrentHashMap----------------72相关推荐
- Java并发编程实战读书笔记三
第七章 取消和关闭 Java没有提供任何机制来安全的终止线程,虽然 Thread.stop 和 suspend 等方法提供了这样的机制,但由于存在着一些严重的陷,因此应该避免使用 7.1任务取消 7. ...
- Java并发编程实战————Executor框架与任务执行
引言 本篇博客介绍通过"执行任务"的机制来设计应用程序时需要掌握的一些知识.所有的内容均提炼自<Java并发编程实战>中第六章的内容. 大多数并发应用程序都是围绕&qu ...
- 《Java 并发编程实战》--读书笔记
Java 并发编程实战 注: 极客时间<Java 并发编程实战>–读书笔记 GitHub:https://github.com/ByrsH/Reading-notes/blob/maste ...
- Java并发编程实战笔记2:对象的组合
设计线程安全的类 在设计现车让安全类的过程之中,需要包含以下三步: 找出构成对象状态的所有变量 找出约束状态变量的不变性条件 建立对象状态的并发访问策略 实例封闭 通过封闭机制与合适的加锁策略结合起来 ...
- aqs clh java_【Java并发编程实战】—– AQS(四):CLH同步队列
在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形. 其主要从双方面进行了改造:节点的结构与节点等待机制.在结构上引入了 ...
- Java并发编程实战_不愧是领军人物!这种等级的“Java并发编程宝典”谁能撰写?...
前言 大家都知道并发编程技术就是在同一个处理器上同时的去处理多个任务,充分的利用到处理器的每个核心,最大化的发挥处理器的峰值性能,这样就可以避免我们因为性能而产生的一些问题. 大厂的核心负载肯定是非常 ...
- JAVA并发编程实战-任务执行
目录 思维导图 1 在线程中执行任务 1.1 顺序执行任务 1.2 显式的为任务创建线程 1.3 无限制创建线程的缺点 2 Executor框架 2.1 使用Executor实现WebServer 2 ...
- 【极客时间】《Java并发编程实战》学习笔记
目录: 开篇词 | 你为什么需要学习并发编程? 内容来源:开篇词 | 你为什么需要学习并发编程?-极客时间 例如,Java 里 synchronized.wait()/notify() 相关的知识很琐 ...
- Java并发编程实战基础概要
文章目录 Java并发编程实战基础概要 开篇 多线程问题有啥难点呢? 为啥要学习并发编程? 并发问题的根源是什么? CPU切换线程执导致的原子性问题是如何发生的? 缓存导致的可见性问题是如何发生的? ...
- Java并发编程实战之互斥锁
文章目录 Java并发编程实战之互斥锁 如何解决原子性问题? 锁模型 Java synchronized 关键字 Java synchronized 关键字 只能解决原子性问题? 如何正确使用Java ...
最新文章
- SCI论文投稿全程模板
- 统计学习方法笔记(一)-k近邻算法原理及python实现
- Waymo自动驾驶报告:平均21万公里一次事故,严重事故都是人类司机的锅
- 【刷算法】两个链表的第一个公共结点
- 87. Leetcode 343. 整数拆分 (动态规划-基础题)
- 关于SharePoint 2010体系架构的几个话题
- hive选择mariadb还是mysql_Hive MariaDb的安装
- Android :ScaleAnimation
- [转载]最小生成树-Prim算法和Kruskal算法
- “谷歌金山词霸”换汤不换药 实验结果令人失望
- 小程序下拉刷新,如何等待数据返回再收起loading
- 工作中那些让人印象深刻的BUG(2)
- 编译原理考试大题分析【太原理工大学】
- ThingsBoard 二次开发之源码分析 5-如何接收 MQTT 连接
- Zotero修改英文文献的“等”为“et al”
- 支藏人元及五行四时旺衰
- 戴森向小狗下刀,吸尘器市场中外乱战开启?
- 19 | 防火墙:如何和黑客“划清界限”?
- FE内容付费系统响应式(带手机版) v5.46
- 出国留学,转计算机编程学习入门以及面试经验之一家之言