ArrayList在添加元素的时候会出现的一些线程不安全的现象
来源:互联网 发布:费根鲍姆常数 知乎 编辑:程序博客网 时间:2024/05/16 15:07
再学习多线程编程的时候,看到如下代码。
package com.cbf4life;import java.util.*;public class ThreadSafeDemo { public ThreadSafeDemo() { ThreadGroup group=new ThreadGroup("testGroup"); MyThread at=new MyThread(); for(int i=0;i<10000;i++){ Thread th=new Thread(group,at,String.valueOf(i)); th.start(); } while (group.activeCount() > 0) { try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println(at.list0.size()); System.out.println(at.list0.get(0)); } public static void main(String[] args) { new ThreadSafeDemo(); } class MyThread implements Runnable { List<String> list0=new ArrayList<String>(); //thread not safe// Vector<String> list0=new Vector<String>(); //thread not safe// List<String> list0=Collections.synchronizedList(new ArrayList<String>()); //thread safe public void run() { try { Thread.sleep((int)(Math.random()*2)); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } list0.add(Thread.currentThread().getName()); } }}
这段代码的原意是举例说明ArrayList是线程不安全的,然后在运行的时候可能会出现多种结果,
第一种结果
9976
0
大致原因是list的add方法导致的。
/** * Appends the specified element to the end of this list. * * @param e element to be appended to this list * @return <tt>true</tt> (as specified by {@link Collection#add}) */public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true;}这个是list的add方法,
elementData[size++] = e;
这一段代码块就是问题所在,size++这个过程可以分为三步
1.从内存中取到size的值。
2.计算size的值。
3.将size的值写到内存当中。
这不是一个原子性的操作,当多线程添加的情况下,假如size=0时,添加第一个元素的线程添加成功,同时在size没有及时写到内存中时,这时另一个线程继续添加就覆盖了原来的值导致最终list的值为9976。
第二种结果
9976
1
按道理说结果应该是9976 0,但是还是上面说的原因,原来的0被1覆盖了。
第三种结果
数组下标越界异常
原因可能出现在数组扩容的时候,假如当前数组的大小为8,而我添加第7个元素的时候,数组当前不需要扩容。然后这个线程进入阻塞,另一个线程也添加元素,发现当前数组大小还有一个容量,于是添加成功已经有8个元素,然后前一个阻塞线程开始添加元素,然后数组没有扩容,所以数组就容不下这个元素,于是数组下标越界了。
这个例子是在说明ArrayList的非线程安全的特性。
阅读全文
0 0
- ArrayList在添加元素的时候会出现的一些线程不安全的现象
- 线程不安全的ArrayList
- ArrayList的线程不安全问题
- dnsmasq 在和 zk1 和 zk2 这种配合的时候会出现无法解析的现象
- 为什么说ArrayList是线程不安全的?
- 为什么说ArrayList是线程不安全的?
- 为什么说ArrayList是线程不安全的?
- 为什么说ArrayList是线程不安全的?
- 关于NDoc在生成帮助文档的时候会出现的一些问题
- scrolloView点击按钮实现滑动的时候有时候会出现卡顿的现象
- C#编译时出现“不安全代码只会在/unsafe编译的情况下出现”
- 网站被百度降权的时候会出现哪些现象
- 不安全的代码只会在使用/unsafe编译的情况下出现
- 在hadoop启动的时候,会出现各种各样的问题
- 在hadoop启动的时候,会出现各种各样的问题
- 在hadoop启动的时候,会出现各种各样的问题
- 在hadoop启动的时候,会出现各种各样的问题
- 解决遍历迭代器时添加元素会出现异常的问题
- 有关子集枚举和容斥的一些问题
- 标准导航栏
- liunx 查看端口号
- hadoop错误INFO util.NativeCodeLoader
- 伯努利方程
- ArrayList在添加元素的时候会出现的一些线程不安全的现象
- 使用Jmeter进行http接口测试
- Nginx的安装与配置(PHP)
- 17
- Java代码规范
- HashMap使用
- 网络编程---HTTP协议加强
- Google Guava (14.0) Part1
- Ionic2自定义组件的使用