面试题答案
一键面试常见线程安全集合
- Vector:
- 简介:是一个动态数组,与
ArrayList
类似,但它是线程安全的。 - 使用场景:适用于需要线程安全的动态数组场景,不过由于其同步机制,性能相对
ArrayList
较差,不适合高并发读写频繁场景。 - 方法调用:与
ArrayList
类似,如add(E e)
添加元素,get(int index)
获取元素等。
- 简介:是一个动态数组,与
- Hashtable:
- 简介:是一个散列表,实现了
Map
接口,键值对都不能为null
,线程安全。 - 使用场景:适用于需要线程安全的键值对存储场景,性能不如
ConcurrentHashMap
,不适合高并发读写频繁场景。 - 方法调用:
put(K key, V value)
添加键值对,get(Object key)
获取值等。
- 简介:是一个散列表,实现了
- ConcurrentHashMap:
- 简介:线程安全的哈希表,允许多个线程同时读,部分线程写,采用分段锁机制提高并发性能。
- 使用场景:高并发读写场景,是
Hashtable
的高效替代。 - 方法调用:
put(K key, V value)
添加键值对,get(Object key)
获取值,compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)
可用于原子性更新值等。
- CopyOnWriteArrayList:
- 简介:线程安全的
List
,写操作时会复制底层数组,读操作无锁。 - 使用场景:读多写少场景,因为写操作复制数组开销较大。
- 方法调用:
add(E e)
添加元素,get(int index)
获取元素等。
- 简介:线程安全的
- CopyOnWriteArraySet:
- 简介:基于
CopyOnWriteArrayList
实现的线程安全的Set
,具有唯一性。 - 使用场景:读多写少且需要元素唯一性的场景。
- 方法调用:
add(E e)
添加元素,contains(Object o)
判断是否包含元素等。
- 简介:基于
- ConcurrentSkipListMap:
- 简介:线程安全的有序映射表,基于跳表实现,适用于需要排序的键值对存储且要求线程安全场景。
- 使用场景:当需要线程安全且按键排序的
Map
场景。 - 方法调用:
put(K key, V value)
添加键值对,get(Object key)
获取值,firstKey()
获取最小键等。
- ConcurrentSkipListSet:
- 简介:线程安全的有序
Set
,基于ConcurrentSkipListMap
实现。 - 使用场景:需要线程安全且元素有序的
Set
场景。 - 方法调用:
add(E e)
添加元素,contains(Object o)
判断是否包含元素,first()
获取最小元素等。
- 简介:线程安全的有序
多线程环境下正确使用方法
- 合理选择集合:根据读写频率、是否需要排序、元素唯一性等业务需求选择合适的线程安全集合。如读多写少选
CopyOnWriteArrayList
或CopyOnWriteArraySet
;高并发读写选ConcurrentHashMap
等。 - 避免过度同步:虽然这些集合本身线程安全,但不必要的同步操作(如在集合操作外额外加锁)可能降低性能。
- 注意迭代器:部分线程安全集合(如
CopyOnWriteArrayList
)的迭代器创建时基于当时数组快照,迭代过程中数组变化不会反映在迭代器上;而ConcurrentHashMap
迭代器弱一致性,能反映部分修改。使用迭代器时要了解其特性。 - 异常处理:在多线程环境下对集合操作可能抛出异常(如
ConcurrentModificationException
),要合理捕获处理,确保程序健壮性。