在 JDK 1.8 的 ConcurrentHashMap 中,为什么存在两种插入方式?

第3章 zynq MII转GMII的配置和EMIO UART0的配置 本文介绍了在Vivado工程中实现MII转GMII接口适配的过程,同时配置EMIO UART0接口。主要内容包括:修改PS IP核添加UART0接口,使用concat IP核进行信号整合,调整GMII信号引脚连接,添加约束文件定义引脚映射,并最终生成bit流文件。通过详细的操作截图和TCL约束代码,展示了从硬件配置到生成可编程文件的完整流程,为Zynq平台开发提供了实用参考。 阅读详情

在 JDK 1.8 的 ConcurrentHashMap 中,之所以对“容器为空”和“计算位置为空”采取不同的处理方式,主要是因为 并发场景下的性能优化和并发安全保证。我们可以分开来看这两种情况:

1. 容器为空时,使用 volatile + CAS 初始化

  • 原因:ConcurrentHashMap 采用 懒加载,并不会在构造时就初始化所有桶(Node<K, V>[] table)。

  • 实现:当第一次插入元素时,会先判断 table 是否为空:

if (tab == null || (n = tab.length) == 0) 
    tab = initTable();
  • initTable() 方法使用 CAS(Compare-And-Swap) 操作来保证线程安全的初始化。

  • 为什么用 CAS 而不是 synchronized?

    • 目的是减少不必要的锁竞争,提高并发性能。
    • 由于初始化操作通常只需要执行一次(典型的 双重检查锁 模式),CAS 在多数情况下不会失败,所以开销较小。

2. 计算出的位置为空时,使用 CAS 插入

  • 原因:如果某个桶(即 table[index])位置为空,说明没有哈希冲突,我们可以直接尝试插入数据。
  • 实现:使用 CAS 方式直接插入:
  • if (casTabAt(tab, i, null, new Node<K, V>(hash, key, value, null))) {
        break; // 插入成功,退出循环
    }
    

    为什么用 CAS 而不是 synchronized?

  • 因为这个位置是 null,没有竞争,所以可以直接尝试用 无锁的 CAS 操作 插入,避免加锁的开销,提高性能。

3. 计算出的位置不为空时,使用 synchronized

  • 原因:如果 table[index] 位置已经有元素了,可能会遇到 哈希冲突,需要遍历该链表或红黑树进行替换或追加。

  • 实现:

    • 先通过 synchronized 锁住该桶(synchronized (f))。
    • 然后遍历这个桶:
      • 如果 key 已存在,则更新 value。
      • 如果 key 不存在,则添加新的节点(链表 or 红黑树)。
    • 插入完成后,判断链表长度是否达到阈值(8),如果达到就转换为红黑树。
  • 为什么用 synchronized 而不是 CAS?

    • CAS 只能保证单个变量的原子性,而不能保证整个链表或树结构的原子性。
    • 当多个线程同时修改一个桶时,直接用 synchronized 保护整个桶的操作,避免复杂的 CAS 失败重试,提高效率。

JDK 1.8 在 ConcurrentHashMap 中通过 分阶段使用 CAS 和 synchronized,既保证了 高并发性能,又保证了 线程安全,这就是它不同情况下采用不同方式的原因。

TIA博途WINCC的触摸屏VB脚本入门指南(嵌入式) 通过编写事件处理程序,您可以响应触摸屏元素的各种事件,并实现自定义的功能。本文将为您提供TIA博途WINCC触摸屏VB脚本的入门指南,帮助您了解基本的脚本编写和嵌入式开发。假设我们有一个名为"Button1"的按钮元素,当用户点击该按钮时,触发相应的事件处理程序,并在触摸屏上显示一条消息。然后回到触摸屏界面编辑器,在按钮元素的属性窗口中找到"按下"事件,并选择刚才创建的脚本文件作为事件处理程序。现在,当用户点击按钮时,触摸屏将执行相应的事件处理程序,并显示一条消息框,内容为"按钮被点击了! 阅读详情

相关推荐

2024最新版Anaconda Navigator安装使用指南

本文简要介绍如何下载安装Anaconda Navigator最新版,以及如何使用Python内核搭载来完成应用程序开发。

jackson_lingua的博客 1万+

【最佳实践】使用 CAS 方式并发插入或更新数据到数据库 2021-08-17

CAS 并发更新或者插入一条数据使用场景Java 核心代码示例MySQL 业务表信息 使用场景 消费消息队列MQ的消息,持久化到DB时。 可能会有并发操作的业务中。 Java 核心代码示例 import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.RandomUtils; import org.springframework.dao.DuplicateKeyException; import org.springframework

小方编程的专栏 1658

电脑的kernelbase.dll故障怎么处理?kernelbase.dll是什么文件

kernelbase.dll​是一个系统文件,属于Microsoft Windows操作系统的一部分。该DLL(动态链接库)文件包含了许多基本且低级的系统函数,这些函数被Windows上运行的各种程序和进程调用。kernelbase.dll通常与Kernel32.dll紧密相关,它是实现许多Windows API(应用程序编程接口)的封装。这些API涉及到内存管理、输入输出操作、进程和线程管理以及其他许多核心的操作系统功能。

电脑修复君的博客 4533

数据插入一种基于CAS的无锁并发HashTable设计及C代码实现

发一下牢骚和主题无关: 在多线程环境下,我们常经常使用Java的ConcurrentHashMap,但其实这个Map仍然是要应用锁的,只不过应用了一种被称为StripeLock的方式。这里我们试着实现一个完全无锁的HashTable。 首先我们必须弄清楚HashMap有哪些操纵,哪些地方是临界区(CriticalRegion),哪里不是。一个完整的Hash...

weixin_30287169的博客 173

深信服桌面云实战:从零部署到高效运维的配置全景指南

本文详细介绍了深信服桌面云从零部署到高效运维的全流程配置指南,涵盖硬件规划、平台部署、虚拟桌面发布、终端管理及性能优化等关键环节。特别强调了双万兆网络架构、分布式存储配置和智能调度功能的应用,帮助用户实现高性能、高可用的虚拟桌面环境。

weixin_28568819的博客 401

WinForm多语言切换实战:5分钟搞定中英文界面(附完整代码)

本文提供了WinForm应用实现中英文界面切换的两种高效实战方案。通过利用内置的本地化机制和资源文件,开发者可以在5分钟内为窗体添加多语言支持,并附有完整代码示例,帮助快速应对软件国际化需求。

weixin_29230773的博客 406

ConcurrentHashMap中什么时候用CAS,什么时候用Synchronized

简单来说,CAS用于在数组中插入新的节点,synchronized用于在链表或红黑树中添加或删除节点。ConcurrentHashMap在JDK1.8中使用了CAS和synchronized来实现线程安全。

qingyuwp的博客 552

考虑风和浪的影响的旋筒帆船航线优化方法研究

针对旋筒帆船进行航线优化的实现方法,包括升阻力系数的数值模拟、升阻力系数的多元非线性回归建模、旋筒帆船6DOF摇荡运动建模分析以及考虑风、浪影响的旋筒帆船的航线优化研究。

m0_63225885的博客 1163

CAS 是什么?原理及在双向链表中的应用

CAS(Compare and Swap)是一种用于实现并发控制的技术。它是一种乐观锁策略,常用于多线程环境下的数据同步操作。

m0_57836225的博客 1346

手把手教你学Simulink--基于Simulink的近端策略优化(PPO)路径规划仿真建模

本文详细介绍了如何利用Simulink进行近端策略优化(PPO)路径规划的仿真建模。首先,文章概述了PPO路径规划的特点和挑战,强调了其在连续或离散动作空间问题中的高效性和稳定性。接着,列出了所需的工具和环境,包括MATLAB/Simulink、Reinforcement Learning Toolbox等。随后,文章分步骤详细讲解了从定义任务需求到验证与分析的整个仿真建模过程,包括创建Simulink项目、集成智能体模型、构建环境模型、编写PPO路径规划逻辑、将逻辑集成到Simulink模型中以及最终的验

MHD0815的博客 166

OpenCV实战之人脸美颜美型(八)——大眼(下)

我们需要将上述描述量化表达,以r代表上述变形区域的圆的半径,X表示原始图像像素到变形圆圆心的距离,Y表示像素变形后的其距离变形圆圆心的距离,则其形状大致如下图所示。如下图所示,我们可以规定处理区域为眼睛为圆心的一个圆形,从圆心区域开始图像会放大,但该放大的比例随着距离圆心的距离而变小,直至边缘区域的放大比例为0。不过在实际图像变形操作中我们要从目标图像映射到原图,因此我们需要将X/Y调换,让X表示变形后图像的像素距离变形圆中心的距离,Y表示原图像素距离变形圆中心的距离,则其形状如下图所示。

On my way 901

JDK1.8中 ConcurrentHashMap 中的CAS 和 synchronized是如何使用的

CAS:在判断数组中当前位置为null的时候,使用CAS来把这个新的Node写入数组中对应的位置 synchronized :当数组中的指定位置不为空时,通过加锁来添加这个节点进入数组(链表<8)或者是红黑树(链表>=8) 详细过程看下面源码 final V putVal(K key, V value, boolean onlyIfAbsent) { if (key == null || value == null) throw new NullPointerEx

willlu10的博客 9216

Vue3 - 详细实现虚拟列表前端虚拟滚动列表解决方案,vue3长列表优化之虚拟列表,解决列表动态高度不固定高度及图片视频图文异步请求加载问题,虚拟列表DOM大量数据同时加载渲染卡顿太慢及下滑列表闪烁

vue3,vue3虚拟列表,用vue3实现一个虚拟列表,长列表高度不一致如何实现虚拟滚动加载列表,虚拟列表有图片视频,图文列表,上万条数据同时渲染解决,长列表dom渲染太卡,列表滚动条加载超多数据,瀑布流,在Vue3中如何实现列表的虚拟滚动,虚拟列表滑动白屏闪烁闪一下,虚拟列表每个项的高度不确定,可动态改变高度,vue3虚拟滚动列表,页面数据太多加载很慢怎么办,vue3实现不定高的虚拟列表,定高和不定高,虚拟列表非固定高度,vue3长列表优化之虚拟列表实现,vue3虚拟列表高度不固定,用vue3实现一个虚拟

🏆 前端领域优质创作者 1万+

hashmap put过程_HashMap 为什么线程不安全?

优质文章,及时送达前言:我们都知道HashMap是线程不安全的,在多线程环境中不建议使用,但是其线程不安全主要体现在什么地方呢,本文将对该问题进行解密。1.jdk1.7中的HashMap在jdk1.8中对HashMap做了很多优化,这里先分析在jdk1.7中的问题,相信大家都知道在jdk1.7多线程环境下HashMap容易出现死循环,这里我们先用代码来模拟出现死循环的情况: 1 public cl...

weixin_39869733的博客 185

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

hashmap为什么是线程不安全的_面试官:你说 HashMap 线程不安全,它为啥不安全呢?...

扫描下方海报试读本文来源:http://cnblogs.com/developer_chan/p/10450908.html我们都知道HashMap是线程不安全的,在多线程环境中不建议使用,但是其线程不安全主要体现在什么地方呢,本文将对该问题进行解密。1.jdk1.7中的HashMap在jdk1.8中对HashMap做了很多优化,这里先分析在jdk1.7中的问题,相信大家都知道在jd...

weixin_39557419的博客 147

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

hashmap为什么是线程不安全的_HashMap 为什么线程不安全?

1.jdk1.7中的HashMap1.1 扩容造成死循环分析过程1.2 扩容造成数据丢失分析过程2.jdk1.8中HashMap总结前言:我们都知道HashMap是线程不安全的,在多线程环境中不建议使用,但是其线程不安全主要体现在什么地方呢,本文将对该问题进行解密。1.jdk1.7中的HashMap在jdk1.8中对HashMap做了很多优化,这里先分析在jdk1.7中的问题,相信大家都知道在jd...

weixin_39963853的博客 73

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

《JDK 1.7 vs JDK 1.8 ConcurrentHashMap 深度对比与实战解析》

JDK 1.8的ConcurrentHashMap通过细粒度锁(CAS+synchronized)、红黑树优化和多线程协同扩容,显著提升了并发性能和数据安全性。而JDK 1.7的分段锁设计虽在当时优化了并发,但在高竞争场景下仍存在性能瓶颈。理解两者差异,有助于在实际开发中选择合适的版本并规避潜在问题。

欢迎来到我的技术空间!我是【大·南瓜糊胡】,在这里,我分享编程学习的心得、项目开发的经验以及对科技趋势的独特见解。以积极向上的态度探索代码的世界,让编程不仅成为解决问题的工具,更是表达创意与实现梦想的途径,希望我的博客能给你带来灵感与帮助。 1482

jdk1.8的HashMap和ConcurrentHashMap

转自乒乓狂魔 本文针对jdk1.8的ConcurrentHashMap1.8的HashMap设计1.1 整体概览HashMap采用的是数组+链表+红黑树的形式。数组是可以扩容的,链表也是转化为红黑树的,这2种方式都可以承载更多的数据。用户可以设置的参数:初始总容量默认16,默认的加载因子0.75初始的数组个数默认是16(用户不能设置的)容量X加载因子=阈值一旦目前容量超过该阈值,则执行扩容操作。什么

李智正在学习的博客 2360

1.7与1.8下hashmap和ConcurrentHashMap的区别

JDK 1.7与JDK1.8用法 hashmap: (1)存储方式:1.7:hashmap以数组和链表形式进行存储 1.8:hashmap以数组和链表以及红黑树方式进行存储 (2)插入方式: 1.7:链表以头插法的形式进行插入,在并发情况下又可能造成链表死循环,数组值大于阈值时,要先判断插入位置是否为空,不为空才会进行扩容 1.8:链表形式以尾插法进行插入,不会发生死循环情况,同时在put时只要数组范围大于阈值就进行扩容,不需要判断插入位置是否为空,同时在size大于64之后会将链表长度大于8的进行红黑树

qq_44439422的博客 444

ConcurrentHashMap底层演进:JDK1.7分段锁与JDK1.8CAS+局部锁的设计差异

本文将从 “结构设计”“锁机制原理”“性能对比” 三个维度,深度拆解 ConcurrentHashMap 的底层演进逻辑,带你理解不同版本设计的优劣与适用场景。

y245166349的专栏 972

HashMap 在 JDK 1.7 中为什么会出现死循环

JDK1.7的HashMap在多线程扩容时存在死循环问题 摘要:JDK1.7的HashMap在多线程并发扩容时,由于使用头插法转移链表且未加锁,可能导致链表形成环形结构。具体表现为:多个线程同时进行resize操作时,对同一桶链表的节点转移顺序可能被打乱,最终形成e1→e2→e1的闭环链表,导致后续遍历时出现死循环。该问题在JDK1.8中通过改用尾插法和synchronized锁机制得以解决。

chenxuefeng_accp的专栏 1513

java集合-ConcurrentHashMap源码概述(基于JDK1.8)

一,概述

baidu_32689899的博客 411

分析多线程下jdk1.8之前hashmap的put方法造成死循环而jdk1.8之后如何解决这个死循环

美团技术博客 图解HashMap(一) HashMap多线程死循环问题(调试查看) HashMap中傻傻分不清楚的那些概念 Java的HashMap是非线程安全的,在多线程下应该使用ConcurrentHashMap。感谢Doug Lea老爷子的concurrent包。 为什么会发生死循环?(我觉得是这个链表头插法加上没有同步的控制造成的环) 主要还是因为HashMap的底层数据结构...

Elon Zero的博客 3878

5.jdk1.7与1.8的HashMap和ConcurrentHashMap

1.7的HashMap设计1 1.8的HashMap设计1.1 整体概览HashMap采用的是数组+链表+红黑树的形式。数组是可以扩容的,链表也是转化为红黑树的,这2种方式都可以承载更多的数据。用户可以设置的参数:初始总容量默认16,默认的加载因子0.75初始的数组个数默认是16 容量X加载因子=阈值(如第一次扩容16*0.75=12个)一旦目前容量超过该阈值,则执行扩容操作。什么时候扩容?·  ...

郑学炜的技术博客 408

深入浅出ConcurrentHashMap

JDK1.7和1.8下的ConcurrentHashMap的区别比较大,在1.7的版本下ConcurrentHashMap是由Segment + HashEntry分段锁的方式实现,但是在1.8的版本下,ConcurrentHashMap抛弃了Segment,转而拥抱了CAS+syncronizedHashTable:使用了syncronized关键字对put等操作进行加锁:使用分段锁机制实现:使用数组+链表+红黑树结构和CAS。

goat的博客 1077

JDK1.8中HashMap的底层实现

jdk1.7: 数组 + 链表jdk1.8: 数组 + 链表 + 红黑树根据源码可知: 数组默认初始长度为16链表转为红黑树条件: 数组长度64,链表长度为8红黑树退化为链表: 当链表长度为6(避免因在8附近导致链表/红黑树频繁转化)

footbridge的博客 936
上一篇: Session、Cookie、Token的区别
format_push
博客等级 码龄4年 104粉丝 80原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值