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

网站 不 备案semiconductor是什么意思

网站 不 备案,semiconductor是什么意思,郴州网站建设软件定制开发制作,公司网站优化推广方案起因我在定时任务的Service用了ConcurrentHashMap作为缓存&#xff0c;大佬说为什么非要用ConcurrentHashMap。 我们的场景需要用到ConcurrentHashMap吗&#xff1f;&#xff08;我们的场景是一个在读一个在写&#xff09; 用HashMap会导致什么问题。当场其实我闷了 :< 事…

         起因我在定时任务的Service用了ConcurrentHashMap作为缓存,大佬说为什么非要用ConcurrentHashMap。 我们的场景需要用到ConcurrentHashMap吗?(我们的场景是一个在读一个在写) 用HashMap会导致什么问题。
当场其实我闷了 :<    事实上, 最严重的问题是,可能快速失败! 

“快速失败”机制的触发条件

   HashMap 的“快速失败”机制是通过一个名为 modCount 的计数器实现的。任何会修改结构的操作(如 putremoveclear)都会增加这个计数器。

        迭代器(例如通过 keySet().iterator()values().iterator()entrySet().iterator() 亦或者 stream流操作时 anyMatch()allMatch()noneMatch(),findFirst()findAny())在创建时会记录当前的 modCount 值。在迭代器遍历的每个下一个元素之前,它会检查当前的 modCount 是否与之前记录的值相等。如果不相等,就立即抛出 ConcurrentModificationException

         HashMap在多线程环境下的问题

        Java 的 HashMap 不能安全地用于多线程环境,主要是因为它不是线程安全的(not thread-safe)。如果多个线程同时访问一个 HashMap 实例,且至少有一个线程修改了 HashMap 的结构(比如 putremove 等操作),就可能会导致以下问题:

1. 死循环(Dead Loop)或 CPU 100%

这是 HashMap 在多线程环境下最著名的“经典”问题,主要出现在 JDK 1.7 及更早版本

  • 原因:在多线程同时进行 put 操作时,如果触发了扩容(resize)HashMap 会将旧数组中的链表重新哈希到新数组。
  • 在 JDK 1.7 中,扩容时采用的是头插法(将原链表的节点逐个插入到新链表的头部),这在多线程环境下可能导致链表形成环形结构
  • 一旦链表成环,当某个线程执行 get() 操作遍历链表时,就会陷入无限循环,导致 CPU 使用率飙升至 100%。

但是JDK 1.8 改用了尾插法(保持原有顺序插入链表尾部),解决了链表成环的问题,因此在扩容时不会形成环形链表,避免了死循环。


2. 数据丢失(Data Loss)

即使在 JDK 1.8 中解决了死循环问题,HashMap 仍然不是线程安全的,可能导致数据丢失。

  • 多个线程同时执行 put 操作时,由于没有同步机制,一个线程的写入可能覆盖另一个线程的写入
  • 例如:线程 A 和线程 B 同时对同一个 key 进行 put,最终可能只有一个值被保留,另一个被覆盖,导致数据不一致。

3. 数据不一致(Inconsistent Data)

  • 一个线程正在遍历 HashMap(如使用 iterator),而另一个线程修改了 HashMap 的结构(如 put 或 remove),这时遍历线程可能会抛出 ConcurrentModificationExceptionfail-fast 机制)。
  • 即使没有抛出异常,读取到的数据也可能是不一致的中间状态。

4. 竞态条件(Race Condition)

  • HashMap 的内部状态(如 sizetable 数组等)在多线程并发修改时,由于缺乏同步控制,可能导致内部状态混乱。

为什么 ConcurrentHashMap 是线程安全的

  ConcurrentHashMap 是 Java 中专门为高并发场景设计的线程安全的哈希表实现, CAS + synchronized(JDK 1.8+) 的机制,实现了细粒度的并发控制,既保证了线程安全,又大大提升了并发性能。

  • 使用 Node 数组 + 链表 + 红黑树 的结构(类似 HashMap
  • 对每个 桶(bucket) 使用 synchronized 锁住第一个节点(头节点)来实现并发控制
  • 大量使用 CAS(Compare and Swap) 操作来无锁更新关键字段(如 sizemodCount 等

        ConcurrentHashMap 如何解决上述的四个问题?

1. 死循环 / CPU 100%(Dead Loop)

  • ConcurrentHashMap 的解决方案
    • 使用 尾插法 进行扩容迁移,保证链表顺序不变。
    • 扩容时对每个桶加锁(synchronized),同一时间只有一个线程能迁移某个桶的链表
    • 使用 forwardingNode 标记正在迁移的桶,其他线程看到后会协助迁移或等待,避免并发修改。
  • ✅ 结论:彻底避免了链表成环,不会出现死循环

2. 数据丢失(Data Loss)

  • 问题根源HashMap 多线程 put 时,一个线程的写入覆盖另一个线程的写入。
  • ConcurrentHashMap 的解决方案
    • 每个 put 操作会先定位到具体的桶。
    • 如果桶为空,使用 CAS 操作 原子性地插入第一个节点。
    • 如果桶非空,使用 synchronized 锁住头节点,串行化该桶的所有写操作
    • 保证每个 put 操作要么成功插入,要么合并(如 putIfAbsent),不会被静默覆盖。
  • ✅ 结论:所有写操作都是原子的,不会丢失数据

3. 数据不一致(Inconsistent Data)

  • 问题根源:一个线程遍历时,另一个线程修改结构,导致 ConcurrentModificationException 或读到中间状态。
  • ConcurrentHashMap 的解决方案
    • 不抛出 ConcurrentModificationException:它的迭代器是 弱一致性(weakly consistent) 的。
    • 迭代器基于创建时的快照,允许其他线程并发修改。
    • 你可能读不到最新的修改,但不会崩溃或进入死循环
    • 提供了 computemergeputIfAbsent 等原子性复合操作,避免“读-改-写”不一致。
  • ✅ 结论:虽然不是强一致性,但保证了安全遍历和原子性更新,避免了不一致导致的崩溃。

4. 竞态条件(Race Condition)

  • 问题根源:多个线程同时修改共享状态(如 sizethreshold),导致状态混乱。
  • ConcurrentHashMap 的解决方案
    • 使用 CAS 操作 更新 sizemodCount 等共享变量。
    • 使用 volatile 关键字保证变量的可见性。
    • 对桶的修改使用 synchronized 锁,保证临界区的互斥访问。
    • 使用 Unsafe 类进行底层原子操作。
  • ✅ 结论:通过 CAS + synchronized + volatile 的组合,彻底解决了竞态条件
http://www.dtcms.com/a/460129.html

相关文章:

  • 山西两学一做网站网站开发实训要求
  • 旅游网站制作视频百度云怎么做电影引流网站
  • 公司电商网站建设新渝网门户网
  • 九江建网站多少钱都江堰市网站建设
  • 网站首页代码在哪里正常网站 月均ip pv
  • 郑州给公司做网站的公司手机优化大师官方免费下载
  • 如何制作自己的网站百度搜不到网站
  • 网站建设包括啥长沙铭万做网站
  • 做网站找我网站建设需要学ps吗
  • 网站开发公司云鲸互创怎么联系网站开发工程师
  • 建站源码下载wordpress排行小工具
  • C 建设个人网站仿《快乐麻花》网站源码
  • 购物网站管理系统中标信息查询
  • 大连做网站哪家公司好软件开发岗位介绍
  • 吉林网站开发公司网站做地图地址
  • 做网站公外贸公司属于什么企业
  • 网站建设 意见征集如何做互联网营销
  • 西安做网站 送百度首页2019做什么类型网站
  • seo优化网站网页教学包装设计的意义
  • 做网站用什么语言数据库专门做招商的网站是什么意思
  • 网站统计排名东莞市官网网站建设平台
  • 用php做网站难吗centos怎么安装wordpress
  • 国外网站设计 网址启东网站建设公司
  • 教育网站开发需求分析中企动力销售工作内容
  • 网站开发项目经理注意事项没有网站可以做seo
  • 怎么制作网站首页做网站不好做
  • 沧州哪家做网站好猪八戒logo设计网站
  • 商城网站建设模板网络服务停用
  • 材料信息价查询网站品牌建设公司排名
  • 网站建设应该考虑哪些问题廊坊seo外包服务