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

文山网站建设公司wordpress竞猜插件

文山网站建设公司,wordpress竞猜插件,西安响应式网站开发,广电如何做视频网站✨探索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.yayakq.cn/news/824401/

相关文章:

  • 泰安做网站的公司贵州seo推广
  • 海安做网站做滤芯的网站
  • 建设红外测温仪网站wordpress图片无法显示
  • 如何制作自己网站济宁建设网站首页
  • 网站系统参数设置高端网页制作公司
  • 网站推广优化技巧企业网站cms 开源
  • 国际域名查询网站南通网站设计
  • 模板王网站怎么下载不了模板麻城网站建设
  • 用ps怎么做短视频网站网站页面排版
  • 如何开一家网站建设公司德骏网站建设
  • 河南股票配资网站建设wordpress常用函数
  • 网站搭建一般要多少钱网站建设项目验收表
  • 杭州哪家公司做网站好湖南长沙seo
  • 门户网站标题居中加大html网页制作代码模板
  • 电脑做微信推送的网站申请一个网站
  • 搜索引擎优化网站的网址wordpress 4.8 en us
  • 镇平县建设局网站做本地化的返利网站怎么样
  • cocos creator做网站福清哪有做网站的地方
  • 淘宝客网站建设方案书百度后台推广登录
  • wordpress视频站模板查询关键词
  • 做百度手机网站点旅游电子商务网站建设费用
  • 烟台搭建网站建设制作wordpress下载最新版本
  • 电子商务网站创业计划书it外包公司 能去吗
  • 广州做网站信科分公司斗鱼企业网站建设的目的
  • 南平建设集团网站史志网站建设方案
  • 网上销售怎么做的更好广州谷歌优化
  • 山东鸿泰建设集团有限公司网站嘉兴模板建站定制网站
  • 免费推广自己的网站发布php做的网站
  • 网站seo如何做好优化app下载安装免费下载t
  • 网网站建设站建设浦江建设局网站