线程安全的容器
Collections包下的容器
Collections.synchronizedList Collections.synchronizedSet Collections.synchronizedMap
或者Vector、HashTable实现线程安全
JUC包下的容器
由HashTable引出ConcurrentHashMap
- HashTable是使用synchronized实现同步,是对一个大的数组加一把锁,锁住的是对象整体。
- ConcurrentHashMap采用的是分段式锁,将大的Map拆分成N个晓得Segment,在put的时候会根据hash来确定具体存放在哪个segment中,Segment内部的同步机制是基于Lock操作的,每个Segment都会分配一把锁。这样访问不同数据段的时候就实现了并发访问。
ConcurrentHashMap
- jdk1.7使用分割分段(segment),形式是Reentrantlock + segment数组+hashEntry数组+链表。
- segment是一种可重入锁(ReentrantLock);HashEntry用于存储键值对数据。
- Jdk1.8使用node数组,摒弃segment概念。形式为:node数组 + 链表/红黑树 + synchronized + cas。
- 其中node只能用于链表的情况下,当冲突链表达到一定阈值(8)时,链表会转换成红黑树。并发控制使用synchronized和cas来操作。
- cas+volatile实现线程安全。
好处:
1. JDK1.8再次实现降低了锁的粒度,JDK1.7版本锁的粒度是基于segment的,包含多个hashEntry,而JDK1.8锁的粒度就是HashEntry
2. 使用红黑树来优化链表
(从HashTable(所有线程都竞争一个synchronized,table锁)->concurrentHashMap(segment -> node)锁的粒度一直在降低)
CopyOnWriteArrayList、CopyOnWritArrayeSet
介绍:
通过创建底层数组的新副本来实现的。当List、Set需要被修改的时候,我们并不修改原有内容,而是对原有数据进行一次复制,将修改的内容写入副本。写完之后,再将修改完的副本替换原来的数据,这样就会保证读写共享操作了。hshuo的面试之路 文章被收录于专栏
作者目标是找到一份Java后端方向的工作 此专栏用来记录从Bilibili、书本、其他优质博客上面学习的内容 用于巩固、总结内容 主要包含Docker、Dubbo、Java基础、JUC、Maven、MySQL、Redis、SpringBoot、SpringCloud、数据结构、杂文、算法、计算机网络、操作系统、设计模式等相关内容