专栏首页立权的博客HashMap 在 Java7 ,Java8 的线程安全问题

HashMap 在 Java7 ,Java8 的线程安全问题

1.Java7 多线程 put

put -> 容量到达上限 -> 扩容(resize) -> transfer (转移旧散列表上的节点到新散列表)

在 transfer 这一步,因为Java7 使用了头插法,可能会导致某个线程的新散列表的某个槽成环

本质问题是 假如一个线程已经 transfer 完毕,因为使用头插法,会把链表逆置(图中原本的 A -> B , 被置为 B -> A)

如此一来,另外一个线程transfer 的时候,会保存一个错误的 A -> B 关系,把 A 当成当前节点 e,把 B 当成下一个节点 next。

但是现在实际的指向关系是 B -> A , 如此一来,e 和 next 先后是

A  B

B  A

A  null

因为使用头插法,在 B 还指向 A 的情况下,把 A 头插到 B 前面,成环,下次访问A或B会造成死循环,空耗CPU资源。

2.Java 8 不再使用上述头插法,但是因为 没有 StoreLoad 屏障,在一般的 TSO CPU模型中,StoreBuffer中的内容无法被及时刷出,可能出现覆盖现象

关于TSO内存模型:https://www.cnblogs.com/lqlqlq/p/13693876.html

假设有两个CPU核心,在跑两个线程,第一个CPU跑线程A,第二个CPU跑线程B

线程A 和 线程B 读取 散列数组的 i 位置 元素为空,所以都打算直接写入内容,线程A写入 m ,线程B写入 n

因为有缓存一致性协议,所以可以把缓存和内存看成一个统一的一致的存储系统

假设 线程 A 所在 CPU 先将 storeBuffer 的内容刷入 存储系统

尔后,线程B 所在 CPU 也把 storeBuffer 的内容刷入存储系统

显然,线程A 的写入会被线程 B 的覆盖

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Mysql各版本 - 从库多线程执行 relay log

    在支持 并行复制的 Mysql 版本中,从库中负责执行 relay log 的 线程 sql_thread 被分成

    执生
  • JDK8;HashMap:再散列解决hash冲突 ,源码分析和分析思路

    首先,有一个问题:假如我们现在有一个容量为16的数组,现在我想往里面放对象,我有15个对象。

    执生
  • 栈论 : 递归与栈式访问,如何用栈实现所有递归操作(幼儿园题目篇)

    找出二叉树中成员变量M为a 和 b 的节点的最小祖先节点(假设a b 只出现一次)

    执生
  • 005.多线程-线程的生命周期

    新建状态: 当创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动)。 如:ThreadTest thread2 = new ThreadT...

    qubianzhong
  • Java并发编程实战系列11之性能与可伸缩性Performance and Scalability

    线程可以充分发挥系统的处理能力,提高资源利用率。同时现有的线程可以提升系统响应性。 但是在安全性与极限性能上,我们首先需要保证的是安全性。 11.1 对性能的...

    公众号-JavaEdge
  • IOCP异步优化

    2. IO操作: CPU会把内存中的程序委托给其他的网络、磁盘等驱动程序,让这些外部的驱动程序来进行具体的处理,处理完成以后再返回给内存程序。对于这两类操作的优...

    小蜜蜂
  • 【Python之旅】第六篇(四)

        我们知道,不同进程之间的内存空间数据是不能够共享的,试想一下,如果可以随意共享,谈何安全?但是一个进程中的多个线程是可以共享这个进程的内存空间中的数据的...

    py3study
  • 为什么 Java 线程没有 Running 状态?

    Java虚拟机层面所暴露给我们的状态,与操作系统底层的线程状态是两个不同层面的事。具体而言,这里说的 Java 线程状态均来自于 Thread 类下的 Stat...

    Java技术栈
  • 学习使用Lock+Conditionk编写三个经典多线程例子

    在jdk5之后的高级并发包里面Lock接口可以替换原来jvm内置的锁synchronized关键字,同理使用Condition接口的await,signal,s...

    我是攻城师
  • Java线程为何没有Running状态?我猜你不知道。

    Java虚拟机层面所暴露给我们的状态,与操作系统底层的线程状态是两个不同层面的事。具体而言,这里说的 Java 线程状态均来自于 Thread 类下的 Stat...

    黄泽杰

扫码关注云+社区

领取腾讯云代金券