博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
并发下的ArrayList、HashMap
阅读量:2055 次
发布时间:2019-04-28

本文共 1024 字,大约阅读时间需要 3 分钟。

并发下的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

你可能感兴趣的文章
Kubelet 中的 “PLEG is not healthy” 到底是个什么鬼?
查看>>
不懂OpenShift,不足以谈云计算!
查看>>
别让自己“墙”了自己
查看>>
让你的网站用上炫酷的中文字体
查看>>
使用 font-spider 对 webfont 网页字体进行压缩
查看>>
云原生服务网格 Istio 1.4 部署指南
查看>>
让 Linux 防火墙新秀 nftables 为你的 VPS 保驾护航
查看>>
Istio 1.4 部署指南
查看>>
贫苦家庭用户的 Envoy xDS 控制平面
查看>>
Kubernetes Pod 网络精髓:pause 容器详解
查看>>
Docker 技术鼻祖 Linux Namespace 入门系列:Namespace API
查看>>
使用 ebpf 深入分析容器网络 dup 包问题
查看>>
Kubelet 中的 “PLEG is not healthy” 到底是个什么鬼?
查看>>
超详细的网络抓包神器 Tcpdump 使用指南
查看>>
从 Kubernetes 资源控制到开放应用模型,控制器的进化之旅
查看>>
从此以后运维与开发过上了没羞没臊的性福生活
查看>>
教你如何优雅地魔改 Grafana 主题,太实用了!
查看>>
让我们来看看回到单体的 Istio 到底该怎么部署
查看>>
超详细的网络抓包神器 tcpdump 使用指南
查看>>
iTerm2 都不会用,还敢自称老司机?(上)
查看>>