【面试官:Java中线程安全的集合你了解多少?】

1. Vector

简介:早期实现的动态数组,通过synchronized方法实现线程安全

优点

  • 简单易用
  • 完全同步保证强一致性

缺点

  • 性能较差(所有方法同步)
  • 迭代时仍需外部同步
  • 扩容机制不够高效

适用场景

  • 低并发环境
  • 需要强一致性的遗留系统

代码示例

Vector<String> vector = new Vector<>();
vector.add("item1");
String item = vector.get(0);

2. Hashtable

简介:早期键值对集合,通过synchronized方法实现线程安全

优点

  • 简单键值存储方案
  • 强一致性保证

缺点

  • 全局锁导致性能差
  • 不允许null键/值
  • 迭代效率低

适用场景

  • 低并发环境下的配置存储
  • 需要同步整个Map的操作

代码示例

Hashtable<Integer, String> table = new Hashtable<>();
table.put(1, "A");
String value = table.get(1);

3. ConcurrentHashMap

简介:分段锁实现的并发Map(JDK8后改用CAS+synchronized)

优点

  • 高并发读写性能
  • 锁粒度小(桶级别)
  • 支持并行批量操作

缺点

  • 迭代弱一致性
  • 计算size时非精确值

适用场景

  • 高并发缓存
  • 实时计数器
  • 高频更新的键值存储

代码示例

ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("count", 0);
map.compute("count", (k, v) -> v + 1);

4. CopyOnWriteArrayList

简介:写时复制实现的线程安全List

优点

  • 无锁读取
  • 迭代安全(快照迭代器)
  • 写操作简单

缺点

  • 写操作开销大(复制数组)
  • 数据短暂不一致
  • 内存占用较高

适用场景

  • 读多写少的监听器列表
  • 不频繁修改的配置列表
  • 事件通知处理器存储

代码示例

CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
list.add("element");
for(String s : list) { // 迭代期间安全
    System.out.println(s);
}

5. BlockingQueue实现类

简介:支持阻塞操作的队列接口(如ArrayBlockingQueue)

优点

  • 完善的生产者-消费者模式支持
  • 提供限时等待操作
  • 多种阻塞策略可选

缺点

  • 容量固定可能造成阻塞
  • 部分实现锁开销较大

适用场景

  • 线程池任务队列
  • 数据管道
  • 流量缓冲

代码示例

BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
queue.put("task");  // 阻塞写入
String task = queue.take();  // 阻塞获取

6. ConcurrentLinkedQueue

简介:基于CAS的无界非阻塞队列

优点

  • 高并发性能
  • 无锁算法
  • 内存一致性保证

缺点

  • 不支持阻塞操作
  • size()方法需要遍历
  • 内存消耗不可预测

适用场景

  • 高吞吐消息队列
  • 无界任务处理
  • 事件总线实现

代码示例

ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();
queue.offer("event");
String event = queue.poll();

选择建议:

  1. Map类型优先选择ConcurrentHashMap
  2. List类型根据读写比例选择:
    • 写多:Collections.synchronizedList
    • 读多:CopyOnWriteArrayList
  3. 队列场景根据需求选择阻塞/非阻塞实现
  4. 遗留系统维护时可继续使用Vector/Hashtable

实际开发中应根据具体场景测试性能表现,特别注意复合操作(如检查-执行模式)仍需额外同步:

ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
if(!map.containsKey(key)) {
    // 仍需同步,因为非原子操作
    synchronized(map) {
        if(!map.containsKey(key)) {
            map.put(key, value);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值