一、线程不安全的原因

jdk1.7和jdk1.8中HashMap都是线程不安全的,那就具体讲一下为什么会线程不安全(两个方面)。

(1)调用put方法

假如有两个线程A和B,A希望插入一个key-value到HashMap中,首先会通过A的key得到桶的索引坐标,然后获取该桶的链表头结点,线程A的时间片用完,而此时B线程被调用执行,和线程A一样执行,只不过线程B成功的将数据插入到桶里面。假设线程A插入时候计算的坐标和B线程要插入的索引坐标是一致的,那么当B线程成功插入以后,线程A再次被调用运行的时候,它依然持有原来的链表头,但是它对B线程插入的过程一无所知,那么线程A就会对此坐标上的数据进行覆盖,那么线程B插入的数据就会消失,造成数据不一致的行为。

(2)扩容

JDK7版本中的HashMap扩容时使用头插法,假设此时有元素一指向元素二的链表,当有两个线程使用HashMap扩容的时,若线程一在迁移元素时阻塞,但是已经将指针指向了对应的元素,线程二正常扩容,因为使用的是头插法,迁移元素后将元素二指向元素一。此时若线程一被唤醒,在现有基础上再次使用头插法,将元素一指向元素二,形成循环链表。若查询到此循环链表时,便形成了死锁。而JDK8版本中的HashMap在扩容时保证元素的顺序不发生改变,就不再形成死锁,但是注意此时HashMap还是线程不安全的。

二:如何解决HashMap线程安全问题?

解决线程安全问题的方式有多种比如:

  1. 比如使用HashTable
  2. 使用Collection.synchronizedMap
  3. 使用ConcurrentHashMap

在使用HashTable或者Collection.synchronizedMap中,这两者有着共同的问题:那就是性能问题。

无论读操作还是写操作,它们都会给整个集合进行加锁,导致同一时间内其他的操作进入阻塞状态。

那么在并发环境下,能够兼顾线程安全和运行效率的情况下就要使用concurrentHashMap

concurrentHashMap在JDK1.7和1.8的版本改动比较大

JD1.7底层是使用数组+链表来实现的,使用分段锁来保证线程安全的,将数组分层了16段,给每个Segment分配一把锁,在读每一个Segment的时候先获取对应的锁,所以最多16个线程并发进行操作。

JDK1.8HashMap一样加入了红黑树,使用Node数组+链表+红黑树结构,避免链表过长导致性能的问题,抛弃了Segment分段锁,改为使用CAS+synchronized关键字实现一种更加细粒度的锁,将锁的级别控制在了更细粒度的哈希桶数组元素级别,也就是说只需要锁住这个链表头节点(红黑树的根节点),就不会影响其他的哈希桶数组元素的读写,大大提高了并发度。

数组长度到达64链表长度大于8时,链表转为红黑树

JDK1.8 中为什么使用内置锁 synchronized替换 可重入锁 ReentrantLock?

  • 在 JDK1.6 中,对 synchronized 锁的实现引入了大量的优化,并且 synchronized 有多种锁状态,会从无锁 ->偏向锁 -> 轻量级锁 -> 重量级锁一步步转换。
  • 减少内存开销 。假设使用可重入锁来获得同步支持,那么每个节点都需要通过继承 AQS来获得同步支持。但并不是每个节点都需要获得同步支持的,只有链表的头节点(红黑树的根节点)需要同步,这无疑带来了巨大内存浪费。

【Java】HashMap线程安全问题相关推荐

  1. HashMap线程安全问题详细解析

    1.简介 HashMap是一种非线程安全的数据结构,即在多线程环境下,无法保证其操作的原子性和一致性.在多个线程同时访问HashMap并进行修改操作时,可能会导致数据的不一致性和线程竞争条件的出现. ...

  2. HashMap线程安全问题以及处理方法!

    一:HashMap为什么会有线程安全问题? 我们知道jdk1.7和jdk1.8中HashMap都是线程不安全的,那就具体讲一下为什么会线程不安全(两个方面). ①调用put方法 假如有两个线程A和B, ...

  3. Java多线程——线程安全问题

    一.什么情况下会产生线程安全问题? 同时满足以下两个条件时: 1,多个线程在操作共享的数据. 2,操作共享数据的线程代码有多条. 当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算,就会 ...

  4. Java多线程 - 线程安全问题

    文章目录 1. 什么是线程安全和线程不安全? 2. 自增运算为什么不是线程安全的? 3. 临界区资源和竞态条件 面试题: 什么是线程安全和线程不安全? 自增运算是不是线程安全的?如何保证多线程下 i+ ...

  5. HashMap 线程安全问题

    前言 我们紧接着上节ArrayList 线程安全问题讲下HashMap的线程安全问题. 之前看书,书中经常会提及.HashTable是线程安全的,HashMap是线程非安全的.在多线程的情况下, Ha ...

  6. Java之线程安全问题浅析

    在java开发中确保线程安全已成为基本要求,线程安全就是指某段代码在多线程环境下能够正确的执行,不会出现数据不一致的情况,反之就是非线程安全. 目前解决线程安全的方式有: 线程安全类,如AtomicI ...

  7. Java解决线程安全问题

    文章目录 背景 1. 线程安全问题 1.1 什么是线程安全? 1.2 产生的原因 1.3 实例(买票超卖问题) 1.4 如何确定是否存在线程安全问题? 2. 如何解决线程安全问题? 2.1 不可变(I ...

  8. Java非线程安全问题的解决方法

    非线程安全.非线程安全主要是指多个线程对同一个对象中的同一个实例变量进行操作时会出现值被更改.值不同步的情况,进而影响程序的执行流程.下面用一个示例来学习一下如何解决非线程安全问题. 本案例模拟了多线 ...

  9. java 静态内部类 线程安全问题_静态内部类-以及它的线程安全问题

    最近用上了静态内部类,作为建造者模式. 自然就会有个疑问.静态内部类,会不会有线程安全的问题?因为静态的,那么这个静态内部类是所有的外部类实例共用一个呢(这样会有线程安全的问题), 还是每个实例有自己 ...

最新文章

  1. 在 CentOS 7.0 上源码安装 Xen 4.5
  2. Flow - JS静态类型检查工具
  3. UiPath Level 1-Lesson 2. Variables Data Types Introduction
  4. Docker的镜像使用
  5. c语言指针的自我评价,个人自我评价
  6. 虚函数和抽象函数的区别
  7. leetcode658. 找到 K 个最接近的元素(二分法)
  8. 量子计算机对未来影响,量子计算机和可控核聚变,哪一个对人类未来的影响更大?...
  9. vsco怎么两个滤镜叠加_做图比设计师还快?!这帮饭圈女孩是怎么做到的?
  10. 20行代码教你用python给证件照换底色
  11. python中相对路径怎么写,python相对路径写法
  12. 六个好用的在线代码编辑器,你选哪个?
  13. 计算机二级考试是可以任选一种吗,计算机二级考试内容是什么_可以任意选择吗...
  14. Android版本自带游戏,植物大战僵尸自带花园版
  15. Python 将矩形图片转为圆形图片
  16. FPGA的LPM标准
  17. 计算机怎样保存文件格式,word文档怎样保存为pdf格式
  18. Java借助ffmpeg进行音视频的格式转换(如m4a转mp3)
  19. IT人才缺口百万,高校不行培训机构上
  20. 【原创】被误解的匈牙利命名法

热门文章

  1. msclass 文字滚动_MSClass 图片/文字不间断滚动\间歇滚动\翻屏滚动类
  2. restapi是什么意思_什么是REST
  3. iphone微信代理服务器,微信黑夜模式在哪?在iPhone上,有这两种方法开启
  4. vue点击事件 根据条件判断是否可以点击
  5. Android 自定义 View 最少必要知识,互联网寒冬
  6. php 去掉excel导入字符串所有空格
  7. 宝塔linux面板搭建小程序wss,CentOS系统云服务器宝塔面板安装以及微信小程序服务器搭建...
  8. 利用Javascript制作网页特效(图像特效)
  9. 高德地图使用-车辆轨迹
  10. windows10锁屏唤醒后所有程序都关闭