ArraysList是线程不安全的数据类型。如果多个线程同时访问列表实例,并且至少有一个线程在结构上修改列表,则需要在外部同步。使用Collections.sychronizedList方法是线程安全的。

查看JDK文档,在结构上修改ArraysList的方法有



分析源码发现,在add方法中的elementData[size++] = e;存在线程不安全的风险。

elementData与size都是全局变量,但没有进行sychronization同步处理,elementData是共享的线程不安全的mutable可变数据。

public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable{private static final long serialVersionUID = 8683452581122892189L;

private static final int DEFAULT_CAPACITY = 10;

private static final Object[] EMPTY_ELEMENTDATA = {};

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

transient Object[] elementData; // non-private to simplify nested class access

private int size;    ..................public boolean add(E e) {        ensureCapacityInternal(size + 1);  // Increments modCount!!        elementData[size++] = e;return true;    }

public void add(int index, E element) {        rangeCheckForAdd(index);

        ensureCapacityInternal(size + 1);  // Increments modCount!!        System.arraycopy(elementData, index, elementData, index + 1,                         size - index);        elementData[index] = element;        size++;    }}复制代码

在iterator部分存在线程不安全的风险,原因之一是iterator部分直接使用了ArraysList的add方法ArrayList.this.add(i, e); ,但没有进行sychronization同步处理。

   public ListIteratorlistIterator(int index) {if (index < 0 || index > size)throw new IndexOutOfBoundsException("Index: "+index);return new ListItr(index);    }public ListIteratorlistIterator() {return new ListItr(0);    }public Iteratoriterator() {return new Itr();    }/**     * An optimized version of AbstractList.Itr     */private class Itr implements Iterator<E> {      .......................    }/**     * An optimized version of AbstractList.ListItr     */private class ListItr extends Itr implements ListIterator<E> {        ........................public void set(E e) {if (lastRet < 0)throw new IllegalStateException();            checkForComodification();try {                ArrayList.this.set(lastRet, e);            } catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();            }        }public void add(E e) {            checkForComodification();try {int i = cursor;                ArrayList.this.add(i, e);                cursor = i + 1;                lastRet = -1;                expectedModCount = modCount;            } catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();            }        }    }复制代码

总结

本文通过add和Iterator入手分析ArraysList线程不安全的原因,可能不够全面,欢迎补充,欢迎指正!

·SHARE·

某985工科男,某互联网大厂搬砖工,有一点温度,也有一点理性;有一点有趣,也有一点认真。写一些心得,偶尔也分享一些资源

微信号:程序猿的进阶

simpledateformat线程不安全_ArrayList为什么线程不安全?相关推荐

  1. 并发编程-12线程安全策略之常见的线程不安全类

    文章目录 脑图 概述 字符串拼接子之StringBuilder.StringBuffer StringBuilder (线程不安全) StringBuffer (线程安全) 小结 时间相关的类 Sim ...

  2. java timer 线程安全_多线程之 线程安全与控制

    线程控制 wait和notify方法需要注意的细节:wait方法与notify方法必须要由同一个锁对象调用.因为:对应的锁对象可以通过notify唤醒使用同一个锁对 象调用的wait方法后的线程. w ...

  3. boost创建线程池_Java并发 之 线程池系列 (1) 让多线程不再坑爹的线程池

    目录 背景 线程池的来由 什么是线程池 背景总结 用法 通过Executors创建线程池 Executors及其服务的类 Executors常用的几个方法 一个线程池的例子 任务 池子 测试 说明 总 ...

  4. 线程并发库和线程池的作用_线程和并发介绍

    线程并发库和线程池的作用 本文是我们名为Java Concurrency Essentials的学院课程的一部分. 在本课程中,您将深入探讨并发的魔力. 将向您介绍并发和并发代码的基础知识,并学习诸如 ...

  5. 线程状态,优先级,守护线程基础详解

    线程状态,优先级,守护线程基础详解 线程状态 停止线程 线程休眠 线程礼让 线程强制执行 线程状态检测 线程的优先级 守护线程 线程同步 线程状态 创建状态(new 之后就是创建状态 就绪状态(调用s ...

  6. java线程池存在时间_Java线程池基础

    目录: 一.线程池概述 1.线程池类 目前线程池类一般有两个,一个来自于Spring,一个来自于JDK: 来自Spring的线程池:org.springframework.scheduling.con ...

  7. java 线程 通过interrupted_Java线程的传说(1)——中断线程Interrupted的用处

    中断线程 -- interrupt() 一个正在运行的线程除了正常的时间片中断之外,能否被其他线程控制?或者说其他线程能否让指定线程放弃CPU或者提前结束运行? 除了线程同步机制之外,还有两种方法: ...

  8. Java线程怎样映射到操作系统线程

    先说多线程模型,参考经典教材<Operating System Concepts , Silberschatz ,9th edition> 中文版是<操作系统概念,第9版> h ...

  9. springboot 线程池_Spring boot 2 线程池怎么配置

    线程池 在java 中线程池,就是ThreadPoolExecutor来构造,简单看下线程池包含的方法, corePoolSize:初始化线程.线程池中保留的线程数量. maximumPoolSize ...

最新文章

  1. python【力扣LeetCode算法题库】322-零钱兑换(动态规划)
  2. 如何解决linux的ssh连接自动断开的问题
  3. 科研人必备的学术导航,不看后悔!
  4. python做一个考试系统_1218Python基于Django在线考试系统设计
  5. C++set容器-插入和删除
  6. linux shell 自定义函数(定义、返回值、变量作用域)介绍
  7. 你想成为Java架构师吗?掌握这六项就够了!
  8. phpstudy能安装不带mysql的么_装了phpstudy还需要装mysql吗
  9. oracle查询用户下所有表名称
  10. suse linux vnc 桌面号,在SUSE Linux下安装VNC的方法
  11. C++模板中关键字typename与class的区别
  12. mysql+enable+sql+log_MySQL -- redolog + binlog
  13. 2020年javaWeb面试题(初)
  14. 8086cpu物理寻址
  15. 关于Arcgis runtime sdk for android加载本地.tpk报错Failed to open file. May not be a valid tile package的解决方法
  16. 使用U盘重装win10系统
  17. SLCP验厂辅导,SLCP验证员必须遵守验证协议中的验证规则以确保数据的质量和完整性
  18. k宝无法连接计算机,农行二代K宝插电脑上显示无法识别怎么办? 驱动已正确安装了,电脑的USB接口插其他U盘什么的都正常的...
  19. python 遍历元组_python遍历元祖
  20. 互联网时代网赚项目分析

热门文章

  1. JVM夺命连环10问
  2. Arthas - Java 线上问题定位处理的终极利器
  3. 【中生代技术社区内推】
  4. jeecg 分布式部署附件共享问题(Linux软连接和硬链接)
  5. 个人成长中,关于规划设计的思考
  6. SpringBoot2.0 整合 Swagger2 ,构建接口管理界面
  7. java 中equals和==的区别
  8. macOS上,实现Wireshark手机抓包
  9. HDFS Client 设计实现解析
  10. RHEL6 grub修复