面试题答案
一键面试- 问题:
- 在多线程环境下对
ArrayList
进行操作会出现数据不一致、并发修改异常(ConcurrentModificationException
)等问题。
- 在多线程环境下对
- 原因(从底层逻辑角度):
ArrayList
底层是基于数组实现的。它在添加元素时,如果数组容量不足会进行扩容操作,创建一个新的更大的数组并将原数组内容复制过去。- 在多线程环境下,当一个线程正在进行扩容操作,另一个线程同时进行添加或删除元素操作时,可能会导致数据覆盖、丢失等数据不一致问题。
- 此外,
ArrayList
的迭代器在遍历时会记录初始的modCount
(记录集合结构修改次数的变量),如果在遍历过程中集合结构被其他线程修改,modCount
会发生变化,当迭代器检测到modCount
变化时,就会抛出ConcurrentModificationException
。
- 解决方法:
- 使用
Collections.synchronizedList
:
这会返回一个线程安全的List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>());
List
,它通过在方法调用时使用synchronized
关键字来保证线程安全。 - 使用
CopyOnWriteArrayList
:List<String> copyOnWriteList = new CopyOnWriteArrayList<>();
CopyOnWriteArrayList
在进行写操作(如添加、修改、删除)时,会先复制一份原数组,在新数组上进行操作,操作完成后将原数组引用指向新数组。读操作直接读取原数组,由于读操作不会加锁,所以读操作性能较高,适合读多写少的场景。
- 使用