并发下的ArrayList、HashMap

并发下的ArrayList

情景:两个线程各向同一个ArrayList中添加100 000个元素。

  1. 可能程序正常结束
  2. 抛出角标越界异常ArrayIndexOutOfBoundsException
  public boolean add(E e) {
   		// 1 检查容量,如果超出要扩容
        ensureCapacityInternal(size + 1);
        //2 添加元素
        elementData[size++] = e;
        return true;
    }

列表容量为10,当前已有9个元素 即size = 9;
线程A 进入add()方法,调用 ensureCapacityInternal 进行elementData[] 容量判断;
此时线程B 也进入add()方法,调用ensureCapacityInternal进行容量判断;
线程A 获取size = 9 ,elementData.length =10,无需扩容;
线程B 获取size = 9,elementData.length = 10, 也无需扩容;
线程A 进行赋值elementData[size++] = e 即 elementData[9] = e, size ++ 后 size == 10
线程B进行赋值elementData[size++] = e 即 elementData[10] = e,角标越界
总结:多线程并发操作add(),线程B获取size进行扩容判断时,线程A还没来得及将size加1,所以未触发数组扩容,线程B在赋值时角标越界

  1. 比实际大小小,线程2覆盖了线程1的值

elementData[size++] = e 赋值操作实际上是两步:
elementData[size] = e
size ++ 自增运算同样是线程不安全的;
假设size=5.若线程A在5位置存放了值valueA,获得size=5,但还没来得及将size加1写入主存
此时线程B在也在5位置存放了值valueB,也获得size=5,
而后A、B分别将size加1后写入主存,size=6,即两个线程执行两次add()后size只加了1

解决方案:还没学

https://blog.csdn.net/weixin_35959462/article/details/114061201

并发下的HashMap

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值