日期:2014-05-20  浏览次数:20821 次

Vector线程安全,ArrayList线程不安全问题。
在网上看到的一篇文章,如下:
vector线程安全 ArrayList非线程安全,但却解约系统性能 
比如一个 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。这就是“线程不安全”了。



然后我写了测试的例子。
发现都没有抛出异常啊。是不是我写的例子有问题?谁给我个演示ArrayList线程不安全的列子呢?谢谢了。
Java code

import java.util.Vector;

//实现Runnable接口的线程
public class HelloThread implements Runnable {
    String name;
    Vector v;

    HelloThread(String name,Vector v) {
        this.name = name;
        this.v = v;
    }

    public void run() {
        /*
         * int sleeptime=(int)(Math.random()*3000); ///A try{ //B
         * Thread.sleep(sleeptime); ///C }catch(InterruptedException e){} ///D
         */
        System.out.println(name+"start");
        v.add(name+".add");
    }

    public static void main(String args[]) throws InterruptedException {
        
        Vector v = new Vector();
        
        HelloThread hello1 = new HelloThread("hello1",v);
        HelloThread hello2 = new HelloThread("hello2",v);
        HelloThread hello3 = new HelloThread("hello3",v);

        Thread h1 = new Thread(hello1);
        Thread h2 = new Thread(hello2);
        Thread h3 = new Thread(hello3);
        h1.start();
        h2.start();
        h3.start();

        try { 
            Thread.sleep(1000); 
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }
        
        for(int i=0;i<v.size();i++){
            System.out.println(v.get(i));
        }

    }
}



Java code

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

//实现Runnable接口的线程
public class HelloThread implements Runnable {
    String name;
    List v;

    HelloThread(String name,List v) {
        this.name = name;
        this.v = v;
    }

    public void run() {
        System.out.println(name+"start");
        v.add(name+".add");
    }

    public static void main(String args[]) throws InterruptedException {
        
        List v = new ArrayList();
        
        HelloThread hello1 = new HelloThread("hello1",v);
        HelloThread hello2 = new HelloThread("hello2",v);
        HelloThread hello3 = new HelloThread("hello3",v);

        Thread h1 = new Thread(hello1);
        Thread h2 = new Thread(hello2);
        Thread h3 = new Thread(hello3);
        h1.start();
        h2.start();
        h3.start();

        try { 
            Thread.sleep(1000); 
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }
        
        System.out.println("v.size:"+v.size());
        for(int i=0;i<v.size();i++){
            System.out.println(v.get(i));
        }

    }
}



------解决方案--------------------
对你的程序稍作改动
Java code
package com.xuz.csdn.worldcup.day7;

import java.util.ArrayList;
import java.util.List;

//实现Runnable接口的线程
public class HelloThread implements Runnable {
    String name;
    List<String> v;

    HelloThread(String name, List<String> v) {
        this.name = name;
        this.v = v;
    }

    public void run() {
        System.out.println(name + "start");
        while(true){
            v.add(name + ".add");
            System.out.println(name + " list size is " + v.size());
            
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                System.out.println(e.getMessage());
            }
        }
    }

    public static void main(String args[]) throws InterruptedException {

        List<String> v = new ArrayList<String>();

        HelloThread hello1 = new HelloThread("hello1", v);
        HelloThread hello2 = new HelloThread("hello2", v);
        HelloThread hello3 = new HelloThread("hello3", v);

        Thread h1 = new Thread(hello1);
        Thread h2 = new Thread(hello2);
        Thread h3 = new Thread(hello3);
        h1.start();
        h2.start();
        h3.start();

//        try {
//            Thread.sleep(1000);
//        } catch (InterruptedException e) {
//            System.out.println(e.getMessage());
//        }

//        System.out.println("v.size:" + v.size());
//        for (int i = 0; i < v.size(); i++) {
//            System.out.println(v.get(i));
//        }

    }
}