MST

星途 面试题库

面试题:Java ArrayList并发操作的底层逻辑与问题

在多线程环境下对ArrayList进行操作,会出现什么问题?从ArrayList底层逻辑角度分析原因,并说明如何解决这些问题。
39.4万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

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