JUC集合(java.util.concurrent)
并发编程里常用的集合,由于在高并发的场景下,很多传统的集合不再适用了,所以在JUC包下提供了大量的并发编程场景适用的集合。主要的操作是通过对集合进行加锁操作。主要以阻塞队列和CurrentHashMap为代表。
HashMap 有为什么线程不安全
1.7 数组扩容会导致死循环和数据丢失
1.8 解决了数据丢失和死循环的问题但是会出现数据覆盖的问题
HashMap为什么线程不安全?_花言巧语大佩奇的博客-CSDN博客_hashmap为什么线程不安全
1.7 是transfer 函数导致的 死循环和数据丢失,1.8 的put方法导致数据覆盖。
CurrentHahsMap 实现原理
1.7 使用segment segment 中有多个hashEntity 每一个HashEntity 是一个就是一个链表 会在每一个链表头部添加锁
1.8 valotile 在Node 中修饰value
CAS:在判断数组中当前位置为null的时候,使用CAS来把这个新的Node写入数组中对应的位置
synchronized :当数组中的指定位置不为空时,通过加锁来添加这个节点进入数组(链表<8)或者是红黑树(链表>=8)
JDK1.8中 ConcurrentHashMap 中的CAS 和 synchronized是如何使用的_willlu10的博客-CSDN博客_concurrenthashmap中的cas
下面单独分析CurrentHashMap。
5种常见数据结构:栈,队列,表(hash表),树(二叉树,红黑树,B+),图
1、数据结构Hash表
哈希表就是一种以键值(key-indexed) 存储数据结构,我们只要输入待查找的值即key,即可查找到其对应的值
2、JUC之外的java实现的Hash表
HashMap是线程不安全的,在多线程情况下会发生线程不安全的情况。
HashTable 和HashMap的实现原理几乎一样,差别无非是HashTabe不允许key和value为null。
HashTable 是线程安全的。
3、JUC中的Hash表ConcurrentHashMap
Jdk1.7 版本中ConcurrentHashMap 采用了数组+Segment+分段锁的方式实现的(Segment继承了ReentrantLock),他使用分段锁的方式,将数据分成一段段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段数据也能被其他线程访问,能够实现真正的并发访问。
内部结构:
JDK8 的ConcurrentHashMap 的底层实现原理
JDK8 的实现已经摒弃了Segment的概念,而是使用synchronized+Node数组/红黑树的方式+volatle +CAS
Java 8 中实现的currentHashMap 其实已经和HashMap的结构很像了。简化了数据结构,增加了操作上复杂难度。网上了说的很乱了,我去查了下源码,CurrentHashMap 在实现的方式上在增加了sychronized操作保证操作的原子性且sychronized是锁在Node对象上的。使用volatle关键字修饰node,保证数据的实时刷新,当然了currentHashMap 同样对Node节点进行了优化,节点8个以内Node节点是链表节点,超过8个Node节点为红黑树的子树。