ArrayList线程不安全分析

http://wsmajunfeng.iteye.com/blog/1493941

 

一个 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.
    }
}

Vector线程安全

Vector的所有操作方法都被同步了,既然被同步了,多个线程就不可能同时访问vector中的数据,只能一个一个地访问,所以不会出现数据混乱的情况,所以是线程安全的。

如果不同步的话,对于同一个vector实例,如果第一个线程添加一个数据进去,第二个线程删除一个数据,你说最终结果是vector中有多少个数据?不能确定吧!这就是不同步的结果,所以在多线程下不能保证数据按照你的意思进行处理,也就是线程不安全的。

ArrayList线程不安全的更多相关文章

  1. 集合框架,ArrayList和Vector的区别,让arrayList线程安全的几种方案

    boolean add(E e) 将指定的元素添加到此列表的尾部. void add(int index, E element) 将指定的元素插入此列表中的指定位置. boolean addAll(C ...

  2. ArrayList线程不安全?

    ArrayList是线程不安全的,轻量级的.如何使ArrayList线程安全? 1.继承Arraylist,然后重写或按需求编写自己的方法,这些方法要写成synchronized,在这些synchro ...

  3. ArrayList线程不安全怎么办?(CopyOnWriteArrayList详解)

    ArrayList线程不安全怎么办? 有三种解决方法: 使用对应的 Vector 类,这个类中的所有方法都加上了 synchronized 关键字 就和 HashMap 和 HashTable 的关系 ...

  4. 如何保证ArrayList线程安全

    一.继承Arraylist,然后重写或按需求编写自己的方法,这些方法要写成synchronized,在这些synchronized的方法中调用ArrayList的方法.   二:使用Collectio ...

  5. 关于ArrayList线程安全解决方案

    一:使用synchronized关键字 二:使用Collections.synchronizedList();使用方法如下: 假如你创建的代码如下:List<Map<String,Obje ...

  6. ArrayList 线程安全

    都说ArrayList是线程不安全的,那为什么不安全呢.根据官方提供的源码, 我是这样理解的,ArrayList的成员方法都不是原子操作的,比如add(E)方法,该方法是在集合的尾部加入一个一个元素. ...

  7. 解决ArrayList线程不安全

    前些天做项目时,程序出现意外的问题,经后来分析是使用ArrayList这个线程不安全的方法导致 解决这个问题通常有两种方法(个人认为) 一:使用synchronized关键字,这个大家应该都很熟悉了, ...

  8. 专业写博一天------ArrayList 线程安全

    首先我们要了解什么是线程安全: 首先我们要明白线程的工作原理,jvm有一个main  memory ,而每个线程有自己的working memory,一个线程对一个variable  进行操作时,都要 ...

  9. 完美者的代言-ArrayList线程安全问题

    [b]保证线程安全的三种方法:[/b]不要跨线程访问共享变量使共享变量是final类型的将共享变量的操作加上同步一开始就将类设计成线程安全的, 比在后期重新修复它,更容易.编写多线程程序, 首先保证它 ...

随机推荐

  1. ssh curl 命令理解

    使用一条命令抓取一本小说 curl "http://www.23hh.com/book/1/1019/"|iconv -c -f gbk -t utf8 |sed 's/" ...

  2. linux下一键安装 powershell,的bash脚本

    说明 目前,linux下的powershell约等于pash.希望大家专注mono,关注pash. 一键安装脚本包括for centos6,centos7,ubuntu 14.04  ubuntu 1 ...

  3. Android 获取网络状态

    1.检测网络是否可用 public boolean isNetWorkConnected() { ConnectivityManager cm = (ConnectivityManager)getSy ...

  4. 到目前为止,Linux下最完整的Samba服务器配置攻略 (转)

    http://blog.chinaunix.net/uid-23069658-id-3142052.html 安装平台为UBUNTU 14.04,直接软件中心安装samba, service smb ...

  5. CCNA 6.9

    page 201 show ip route    Correction(05-4)   Basic configuration of R1:   enable configure terminal ...

  6. TrueType, OpenType, PCL和PostScript字体版本nterleaved 2 of 5 Barcode Font Advantage Package

    Interleaved 2 of 5 Barcode Font Advantage Package包含了TrueType, OpenType, PCL和PostScript字体版本. 提供了超过30个 ...

  7. JAVA之关于This的用法

    JAVA之关于This的用法   业精于勤,荒于嬉:行成于思,毁于随.——韩愈 用类名定义一个变量的时候,定义的应该只是一个引用,外面可以通过这个引用来访问这个类里面的属性和方法,那们类里面是够也应该 ...

  8. C/C++学习之基础-001

    1.C++虚函数的工作原理 虚函数(virtual function)需要虚函数表(virtual table)才能实现.如果一个类有函数声明成虚拟的,就会生成一个虚函数表,存放这个类的虚函数地址.若 ...

  9. 同是url参数传进来的值,String类型就用getAttribute获取不到,只能用getParameter获取,而int就两个都可以这是为什么?

    这是因为int的属性是id,这是在被放到modeldriver中的user所具有的属性,传递过来的参数如果和user的属性重名,struts2的有类似beanutil之类的工具会自动封装参数,这时候用 ...

  10. C# 对MongoDB 进行增删改查的简单操作 (转)

    运用到的MongoDB支持的C#驱动,当前版本为1.6.0 下载地址:https://github.com/mongodb/mongo-csharp-driver/downloads 1,连接数据库 ...