如果非要在多线程中使用 ArrayList 会发生什么?

本文探讨了在多线程环境下使用ArrayList时可能出现的问题,通过对比Java 8和11的源码,揭示了Java内存模型(JMM)如何导致数据不一致和异常。通过实例验证和时序图分析,强调了ArrayList本身不是线程安全的,即使对相关变量使用volatile也无法确保线程安全,因为其方法设计未考虑多线程环境。
摘要由CSDN通过智能技术生成

为了便于理解,当时只是通过代码执行顺序说明了异常原因。其实多线程中还会涉及 Java 内存模型,本文就从这方面说明一下。

对比源码

我们先来看看 Java 11 中, add 方法做了什么调整。

Java 8 中 add 方法的实现:

public boolean add(E e) {
    ensureCapacityInternal(size + 1);
    elementData[size++] = e;
    return true;
}
Java 11 中 add 方法的实现:

public boolean add(E e) {
    modCount++;
    add(e, elementData, size);
    return true;
}

private void add(E e, Object[] elementData, int s) {
    if (s == elementData.length)
        elementData = grow();
    elementData[s] = e;
    size = s + 1;
}

两段逻辑的差异在于数组下标是否确定:

  • elementData[size++] = e; ,Java 8 中直接使用 size 定位并赋值,然后通过 size++ 自增
  • elementData[s] = e; size = s + 1; ,Java 11 借助临时变量 s 定位并赋值,然后通过 size = s +
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值