MST

星途 面试题库

面试题:Java中线程安全的集合有哪些及如何使用

请列举出Java集合框架中常见的线程安全集合,并简要说明在多线程环境下如何正确使用它们,比如使用场景、方法调用等方面。
37.8万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

常见线程安全集合

  1. Vector
    • 简介:是一个动态数组,与ArrayList类似,但它是线程安全的。
    • 使用场景:适用于需要线程安全的动态数组场景,不过由于其同步机制,性能相对ArrayList较差,不适合高并发读写频繁场景。
    • 方法调用:与ArrayList类似,如add(E e)添加元素,get(int index)获取元素等。
  2. Hashtable
    • 简介:是一个散列表,实现了Map接口,键值对都不能为null,线程安全。
    • 使用场景:适用于需要线程安全的键值对存储场景,性能不如ConcurrentHashMap,不适合高并发读写频繁场景。
    • 方法调用put(K key, V value)添加键值对,get(Object key)获取值等。
  3. ConcurrentHashMap
    • 简介:线程安全的哈希表,允许多个线程同时读,部分线程写,采用分段锁机制提高并发性能。
    • 使用场景:高并发读写场景,是Hashtable的高效替代。
    • 方法调用put(K key, V value)添加键值对,get(Object key)获取值,compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)可用于原子性更新值等。
  4. CopyOnWriteArrayList
    • 简介:线程安全的List,写操作时会复制底层数组,读操作无锁。
    • 使用场景:读多写少场景,因为写操作复制数组开销较大。
    • 方法调用add(E e)添加元素,get(int index)获取元素等。
  5. CopyOnWriteArraySet
    • 简介:基于CopyOnWriteArrayList实现的线程安全的Set,具有唯一性。
    • 使用场景:读多写少且需要元素唯一性的场景。
    • 方法调用add(E e)添加元素,contains(Object o)判断是否包含元素等。
  6. ConcurrentSkipListMap
    • 简介:线程安全的有序映射表,基于跳表实现,适用于需要排序的键值对存储且要求线程安全场景。
    • 使用场景:当需要线程安全且按键排序的Map场景。
    • 方法调用put(K key, V value)添加键值对,get(Object key)获取值,firstKey()获取最小键等。
  7. ConcurrentSkipListSet
    • 简介:线程安全的有序Set,基于ConcurrentSkipListMap实现。
    • 使用场景:需要线程安全且元素有序的Set场景。
    • 方法调用add(E e)添加元素,contains(Object o)判断是否包含元素,first()获取最小元素等。

多线程环境下正确使用方法

  1. 合理选择集合:根据读写频率、是否需要排序、元素唯一性等业务需求选择合适的线程安全集合。如读多写少选CopyOnWriteArrayListCopyOnWriteArraySet;高并发读写选ConcurrentHashMap等。
  2. 避免过度同步:虽然这些集合本身线程安全,但不必要的同步操作(如在集合操作外额外加锁)可能降低性能。
  3. 注意迭代器:部分线程安全集合(如CopyOnWriteArrayList)的迭代器创建时基于当时数组快照,迭代过程中数组变化不会反映在迭代器上;而ConcurrentHashMap迭代器弱一致性,能反映部分修改。使用迭代器时要了解其特性。
  4. 异常处理:在多线程环境下对集合操作可能抛出异常(如ConcurrentModificationException),要合理捕获处理,确保程序健壮性。