当前位置: 首页 > news >正文

龙华网站优化什么软件可以刷网站排名

龙华网站优化,什么软件可以刷网站排名,苏州餐饮 网站建设,多种东莞微信网站建设✨探索Java基础 ConcurrentHashMap✨ 引言 ConcurrentHashMap 是 Java 中一个线程安全的高效 Map 集合。它在多线程环境下提供了高性能的数据访问和修改能力。本文将详细探讨 ConcurrentHashMap 在 JDK 1.7 和 JDK 1.8 中的不同实现方式,以及它们各自的优缺点。 …

✨探索Java基础 ConcurrentHashMap✨

引言

ConcurrentHashMap 是 Java 中一个线程安全的高效 Map 集合。它在多线程环境下提供了高性能的数据访问和修改能力。本文将详细探讨 ConcurrentHashMap 在 JDK 1.7 和 JDK 1.8 中的不同实现方式,以及它们各自的优缺点。

基本概念

ConcurrentHashMap 是一个线程安全的哈希表实现,适用于高并发场景。它的设计目标是在保证线程安全的同时,提供尽可能高的性能。

JDK 1.7 版本的 ConcurrentHashMap

接下来看一张图片:

数据结构

在 JDK 1.7 中,ConcurrentHashMap 使用 分段锁(Segment) 的设计。每个 Segment 是一个独立的小哈希表,并且每个 Segment 都有自己的锁。这种设计允许多个线程同时访问不同的 Segment,从而提高并发性能。

  • Segment 数组:默认是 16 个 Segment。
  • HashEntry 数组:每个 Segment 内部有一个 HashEntry 数组,用于存储具体的元素。
  • 链表:如果发生哈希冲突,会使用单向链表来存储冲突的节点。

存储流程

  1. 计算 key 的哈希值:通过 key 的哈希值确定 Segment 数组的下标。
  2. 获取 Segment 锁:对对应的 Segment 进行加锁。
  3. 确定 HashEntry 数组下标:再次通过哈希值确定 HashEntry 数组中的下标。
  4. 存储数据:将数据存入 HashEntry 数组中,如果发生冲突,则挂载到单向链表上。
  5. 附图:

扩容机制

  • 基于 Segment:每个 Segment 维护自己的负载因子,当某个 Segment 中的元素数量超过阈值时,该 Segment 会单独进行扩容。
  • 局部扩容:只影响当前 Segment,不会影响其他 Segment。

size 方法

  • 尝试三次不加锁获取 sum:如果三次总数相同,直接返回;否则,加锁计算总和。

JDK 1.8 版本的 ConcurrentHashMap

看图:

数据结构

在 JDK 1.8 中,ConcurrentHashMap 取消了 Segment 设计,采用了与 HashMap 类似的数据结构:数组 + 链表/红黑树。

  • Node 数组:类似于 HashMap 的数组。
  • 链表/红黑树:当链表长度超过一定阈值时,会转换为红黑树以提高查询效率。

存储流程

  1. 计算 key 的哈希值:通过 key 的哈希值确定 Node 数组的下标。
  2. CAS 添加新节点:使用 CAS 操作尝试添加新节点。
  3. 锁定首节点:如果 CAS 失败或需要更新链表/红黑树,使用 synchronized 锁定首节点。
  4. 存储数据:将数据存入链表或红黑树中。

扩容机制

  • 全局扩容:当整个 ConcurrentHashMap 的元素数量超过阈值时,整个数组会进行扩容。
  • 渐进式扩容:多个线程共同参与扩容操作,逐步迁移旧数据到新数组中,降低扩容时的性能开销。

size 方法

  • 类似 LongAdder 的思想:使用 baseCount 和 counterCells 数组来维护计数。
  • 减少竞争:通过分散计数到多个 counterCell 来减少对单个变量的竞争压力。

代码示例

JDK 1.7 版本

// Segment 类
static final class Segment<K,V> extends ReentrantLock implements Serializable {private final int threshold;transient volatile HashEntry<K,V>[] table;transient int count;transient int modCount;// 构造函数Segment(int initialCapacity, float loadFactor) {this.threshold = (int) (initialCapacity * loadFactor);setTable(HashEntry.<K,V>newArray(initialCapacity));}// put 方法V put(K key, int hash, V value, boolean onlyIfAbsent) {lock(); // 加锁try {int c = count;if (c++ > threshold) // 需要扩容rehash();HashEntry<K,V>[] tab = table;int index = hash & (tab.length - 1);HashEntry<K,V> first = tab[index];HashEntry<K,V> e = first;while (e != null && (e.hash != hash || !key.equals(e.key)))e = e.next;V oldValue;if (e != null) {oldValue = e.value;if (!onlyIfAbsent)e.value = value;} else {oldValue = null;++modCount;tab[index] = new HashEntry<>(key, hash, first, value);}return oldValue;} finally {unlock(); // 解锁}}
}

JDK 1.8 版本

// Node 类
static class Node<K,V> implements Map.Entry<K,V> {final int hash;final K key;volatile V val;volatile Node<K,V> next;Node(int hash, K key, V val, Node<K,V> next) {this.hash = hash;this.key = key;this.val = val;this.next = next;}public final K getKey()       { return key; }public final V getValue()     { return val; }public final String toString() { return key + "=" + val; }
}// putVal 方法
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {Node<K,V>[] tab; Node<K,V> p; int n, i;if ((tab = table) == null || (n = tab.length) == 0)n = (tab = resize()).length;if ((p = tab[i = (n - 1) & hash]) == null)tab[i] = newNode(hash, key, value, null);else {Node<K,V> e; K k;if (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))e = p;else if (p instanceof TreeNode)e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);else {for (int binCount = 0; ; ++binCount) {if ((e = p.next) == null) {p.next = newNode(hash, key, value, null);if (binCount >= TREEIFY_THRESHOLD - 1) // 转换为红黑树treeifyBin(tab, hash);break;}if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))break;p = e;}}if (e != null) { // 存在键冲突V oldValue = e.val;if (!onlyIfAbsent || oldValue == null)e.val = value;afterNodeAccess(e);return oldValue;}}++modCount;if (++size > threshold)resize();afterNodeInsertion(evict);return null;
}

总结

  • JDK 1.7:使用分段锁(Segment)和 ReentrantLock,每个 Segment 是一个独立的小哈希表,适合中等并发场景。
  • JDK 1.8:采用 CAS 操作和 synchronized 锁定链表或红黑树的首节点,提供了更细粒度的锁,适合高并发场景。

通过这些改进,JDK 1.8 版本的 ConcurrentHashMap 在性能和并发控制方面有了显著的提升。

觉得有用的话可以点点赞 (*/ω\*),支持一下。

如果愿意的话关注一下。会对你有更多的帮助。

每天都会不定时更新哦  >人<  。

http://www.hkea.cn/news/735510/

相关文章:

  • 济南做网站互联网公司有哪些seo是什么公司
  • 辛集seo网站优化价格许昌网站seo
  • 网站建设后期维护百度快速收录技术
  • 网站建设中的推广工作seo学校培训
  • 上海专业网站建设网百度搜索推广开户
  • 做学校网站素材图片合肥seo代理商
  • 真题真做报名网站淘宝搜索关键词排名
  • 免费的黄冈网站有哪些平台?培训行业seo整站优化
  • 寿县住房与城乡建设局网站真正免费的网站建站平台
  • 常德seo招聘网站seo站长工具
  • 网站开发多久完成俄罗斯搜索引擎yandex推广入口
  • 漳州做网站建设建网站免费
  • 网站建设服务上海广州软文推广公司
  • 做一个网站app需要多少钱web制作网站的模板
  • 网站建设的财务计划新媒体营销策略有哪些
  • 网站建设分金手指专业二八宁波品牌网站推广优化
  • 清远网站建设公司百度游戏风云榜
  • 网上可以自学什么技术win7系统优化软件
  • 嘉兴建站软件如何做好企业网站的推广
  • 在凡科做网站短视频推广
  • 深圳推广公司推荐q群排名优化软件
  • 什么网站做简历模板宁德市医院
  • 用什么软件做公司网站游戏推广赚佣金的平台
  • 购物网站 后台模板河北seo技术培训
  • 聊城建设委员会官方网站google seo
  • 广西建设网郭业棚seo推广具体做什么
  • 武汉网站seo诊断谷歌下载官网
  • 做地方网站能赚钱吗免费seo网站诊断
  • 图片设计在线网站推广优化外包便宜
  • 武汉平价做网站网络软文推广案例