一个 ArrayList ,在添加一个元素的时候,它可能会有两步来完成:
1. 在 Items[Size] 的位置存放此元素;
2. 增大 Size 的值。
在单线程运行的情况下,如果 Size = 0,添加一个元素后,此元素在位置 0,而且 Size=1;
而如果是在多线程情况下,比如有两个线程,线程 A 先将元素存放在位置 0。但是此时 CPU 调度线程A暂停,线程 B 得到运行的机会。线程B也向此 ArrayList 添加元素,因为此时 Size 仍然等于 0 (注意哦,我们假设的是添加一个元素是要两个步骤哦,而线程A仅仅完成了步骤1),所以线程B也将元素存放在位置0。然后线程A和线程B都继续运行,都增加 Size 的值。
那好,现在我们来看看 ArrayList 的情况,元素实际上只有一个,存放在位置 0,而 Size 却等于 2。这就是“线程不安全”了。
线程不安全的例子:
public class ArrayListInThread implements Runnable {
List<String> list1 = new ArrayList<String>(1);// not thread safe
// List<String> list1 = Collections.synchronizedList(new ArrayList<String>());// thread safe
public void run() {
try {
Thread.sleep((int)(Math.random() * 2));
}
catch (InterruptedException e) {
e.printStackTrace();
}
list1.add(Thread.currentThread().getName());
}
public static void main(String[] args) throws InterruptedException {
ThreadGroup group = new ThreadGroup("testgroup");
ArrayListInThread t = new ArrayListInThread();
for (int i = 0; i < 10000; i++) {
Thread th = new Thread(group, t, String.valueOf(i));
th.start();
}
while (group.activeCount() > 0) {
Thread.sleep(10);
}
System.out.println();
System.out.println(t.list1.size()); // it should be 10000 if thread safe collection is used.
}
}
分享到:
相关推荐
使用Collections.sychronizedList方法是线程安全的。 查看JDK文档,在结构上修改ArraysList的方法有 分析源码发现,在add方法中的elementData[size++] = e;存在线程不安全的风险。 elementData与size都是全局变量...
java的 ArrayList的使用与分析
主要介绍了ArrayList源码和多线程安全问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,下面小编和大家一起来学习一下吧
前言:一说到ArrayList的大家可能立马想到的就是:有序、可重复、查找快但是增删慢、线程不安全。但是具体的原因都不是很清楚,本文就会根据这些问题和大家一起去学习。主要会从ArrayList的构造方法、增加元素、删除...
在C#早期版本中已经实现了线程安全的ArrayList,可以通过下面的方式构造线程安全的数组列表:var array = ArrayList.Synchronized(new ArrayList()); 我们从Synchronized方法入手,分析它的源代码看是
来自视频课笔记 面试肯定没问题 包含线程安全的list和不安全的list
其他方面,ArrayList 是非线程安全类,并发环境下,多个线程同时操作 ArrayList,会引发不可预知的错误。?本节课程会带着大家去学习集合底层源码是什么个结构,他在做什么事情,能做到什么事情,会出现的问题以及...
主要介绍了java Vector和ArrayList的分析及比较的相关资料,Vector是多线程安全的,而ArrayList不是,本文主要做对比对这两个方法,需要的朋友可以参考下
ArrayList 源码深度解析 一、重新认识ArrayList 什么是ArrayList? ArrayList是基于数组实现的List类,封装了一个动态再分配的Object...size 表示当前数组的大小,int类型,未使用volatile修饰,非线程安全; modCou
区别是ArrayList不是线程安全的,Vector绝⼤多数⽅法做了线程同步。 LinkedList通过双向链表实现。 源代码分析 1、添加元素到列表尾端(Appends the specified element to the end of this list.) ArrayList:当所需...
注意: Vector线程安全、ArrayList 并发队列 在并发队列上JDK提供了两套实现,一个是以ConcurrentLinkedQueue为代表的高性能队 列,一个是以BlockingQueue接口为代表的阻塞队列,无论哪种都继承自Queue。
不是线程安全的。ArrayList包含了两个重要的对象:elementData(Object[]类型的数组) 和 size 遍历ArrayList时,使用随机访问(即,通过索引序号访问)效率最高 转数组:Integer[] newText = v.toArray(new Integer[v....
因为Vector和ArrayList除了数组扩容有点差别,还有加锁使Vector迈进了线程安全的行列外,底层实现大约是没有太大区别的!基本一致!线程安全问题更是另当别论了!继续往下看就OK! 扩容的区别: 从内部实现机制来讲...
ArrayList 和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector...
第五题 如何保证集合是线程安全的.pdf 第八题 Java并发类库提供的线程池有哪几种 分别有什么特点.pdf 第六题 synchronized和ReentLock有什么区别.pdf 第四题 ArrayList LinkedList Vector的区别.pdf docker讲得最...
一.Animal类的设计要求: 根据实际需求设计Animal类,并完成以下功能: 1. 输出全部信息 2. 对2个实例进行比较 3. 使用static对共同的属性进行修饰 ...8. 利用ArrayList集合收集动物的年龄信息,并对其进行分析。
基于java tcp socket通信的拆包和装包源码 基础 集合 List集合是有序集合,集合中的元素可以重复,访问集合中的元素可以根据元素的索引来访问,查找元素效率...1、Vector是线程同步的,所以它也是线程安全的,而ArrayLi
组件、JMM、线程安全、锁优化 磁盘操作、字节操作、字符操作、对象操作、网络操作、NIO 运行时数据区域、垃圾收集、内存分配机制、类加载机制、性能调优监控工具 Java 常见的 10 余种设计模式,全 23 种设计模式逐步...
ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector...