浅谈集合之线程安全方案

发布时间 2023-03-22 21:13:54作者: Jaywee

List

一般方法

  1. 自定义 ArrayList 子类:手动同步/加锁,复杂度高。

  2. Vector(Java 1.0):

    1. 特点:大量方法签名使用 synchronized 对象锁(全局锁)。
    2. 说明:性能差。
  3. Collections.synchronizedList:(Java 1.2)同步代理类

    1. 特点:引入成员变量 mutex 对象锁,synchronized(mutex)(全局锁)。
    2. 说明:性能不是最优。

CopyOnWriteArrayList(Java 1.5 - JUC)

写时复制

  1. 操作
    1. :直接读取集合本身,无须加锁与阻塞(不加锁)。
    2. :如增删,需要加锁(避免 copy 多个副本)
      1. 线程执行写操作时,copy 一份新的数组。
      2. 对副本执行写操作。
      3. 修改引用
  2. 特点:读写分离,延时更新
    1. 内存使用:写操作会额外产生一份数组,不适合大数据量场景。
    2. 最终一致性:读操作获取一份快照,不适合实时性高的场景。

Map

一般方法

  1. Hashtable:(Java 1.0)同 Vector,全局锁
  2. Collections.synchronizedMap:同 synchronizedList,全局锁

ConcurrentHashMap(JUC)

  1. Java 1.7-分段锁
    1. 将 HashMap 的 Entry 数组拆分为多段(segment)
    2. segment 是 ReentrantLock 实现类,对 segment 加锁可避免锁表。
  2. Java 1.8+:CAS + synchronized(锁头结点