七、线程安全集合类
前言
在数据结构中,我们学习过 Java 的内置集合,但是我们知道,我们学过的大多数集合类都是线程不安全的,少数如 Vector,Stack,HashTable 是线程安全的,但这些都是一些比较“粗糙”的类(在所有方法上加了 synchronized 锁),一般不建议使用。
那么当我们想要在多线程下使用集合类该怎么处理呢?
一、多线程使用线性表
方式1:手动给会出现线程安全问题的逻辑加锁。
例如多个线程修改 ArrayList,此时可能出现问题,就可以给修改操作进行加锁。
方式2:使用 Collections.synchronizedList(); 封装
将想要使用的线性表用上述方法封装起来,相当于给集合里的关键方法加上了锁。

方式3:使用使用 CopyOnWriteArrayList
CopyOnWriteArrayList 原理
> 1. CopyOnWriteArrayList 又称写时复制的容器。当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。
> 2. 这样做的好处是我们可以对 CopyOnWriteArrayList 容器进行并发的读,而不需要加锁(只有在写时加锁),因为当前容 器不会添加任何元素。
> 3. 所以说 CopyOnWriteArrayList 容器采用的是一种读写分离的思想,读和写不同的容器。
优点:
> - 适用于读多写少的场景下。在读多写少的场景下,性能很高,不需要加锁竞争.
缺点:
> - 在修改时需要重新拷贝容器,占用内存较多。 > - 新写的数据不能被第一时间读取到,即可能出现“脏读”问题。
二、多线程使用栈和队列
多线程使用栈和队列,我们可以直接使用 Java 标准库提供的阻塞队列,因为带有阻塞功能,这些集合在多线程下是线程安全的:
> 1. ArrayBlockingQueue 基于数组实现的阻塞队列