You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java集合读操作是否线程安全?有无官方文档支撑该结论?

Java集合读操作的线程安全性探讨

举个例子:

class Test {

    List<Integer> myList = new ArrayList<>();

    public Test() {
      myList.add(1);
      myList.add(2);
    }

    public static void main(String args[]) {
       
        Test obj = new Test();
        Thread t1 = new Thread(() -> { System.out.println(obj.myList.get(0)); });
        Thread t2 = new Thread(() -> { System.out.println(obj.myList.get(1)); });
        t1.start();
        t2.start();
    }
}

上述代码中,通过两个线程读取ArrayList的值。很多代码会将初始化后不再修改的列表的读操作视为线程安全,但理论上,即使调用ArrayList的get()方法也可能改变列表状态(取决于具体实现),因此并非绝对线程安全。

比如我们可以自定义一个ArrayList,用非原子整数记录get()方法的调用次数,这样的get操作就不是线程安全的:

// 仅作示例
void get(int n) {
   get_counter++;
   return array[n];
}

技术问询解答

Java官方文档明确说明,普通非线程安全集合(如ArrayList、HashMap等)的读操作并非天然线程安全,仅在满足特定条件时才安全:当集合完成初始化后,后续没有任何线程对其执行修改操作,此时多线程的读操作不会引发问题。

Java集合框架文档提到,对于非并发集合类,若一个线程在修改集合的同时,有其他线程访问该集合,必然会导致不确定的行为。只有当集合处于"不可变"状态(初始化后不再被修改)时,多线程读操作才不会出现异常,但这并非因为读操作本身具备线程安全性,而是因为不存在修改操作带来的并发冲突。

需要注意的是,官方实现的ArrayList的get()方法本身不会修改集合状态(比如没有额外的计数逻辑),但这是具体实现的特性,而非集合接口的通用约定。不能以此推断所有集合的读操作都是线程安全的,尤其是自定义实现的集合类。

内容的提问来源于stack exchange,提问作者johngreen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 12:57:09