ArrayList vs Vector

大家都知道Vector是线程安全的,ArrayList是不安全的, 现在测试下ArrayList怎么个不安全法

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

public class HelloThread implements Runnable {
	List<String> v = new ArrayList<String>();

	// Vector<String> v = new Vector<String>();

	// synchronized
	public void run() {
		try {
			while (true) {
				System.out.println(Thread.currentThread().getName() + " list size is " + v.size());
				Thread.sleep(3);
				v.add("tristan");

				if (v.size() > 100) {
					System.exit(1);
				}
			}
		} catch (Exception e) {
			System.err.println(Thread.currentThread().getName());
			
			e.printStackTrace();
			
			System.err.println("v.size(): " + v.size());
			System.exit(-1);
		}
	}

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

		HelloThread hello1 = new HelloThread();

		Thread h1 = new Thread(hello1);
		Thread h2 = new Thread(hello1);
		Thread h3 = new Thread(hello1);
		Thread h4 = new Thread(hello1);
		Thread h5 = new Thread(hello1);
		Thread h6 = new Thread(hello1);
		Thread h7 = new Thread(hello1);
		Thread h8 = new Thread(hello1);
		Thread h9 = new Thread(hello1);

		h1.start();
		h2.start();
		h3.start();
		h4.start();
		h5.start();
		h6.start();
		h7.start();
		h8.start();
		h9.start();

	}
}


运行多次可以发现ArrayList有很大的报错概率, Vector则不会,
如何在run 方法上加上同步锁那也不会出现问题, 所以ArrayList的非线程安全性就体现在这里, 多个线程同时操作时可能会出现数组越界的异常。

再来看ArrayList和Vector的源代码,可以发现ArrayList的add方法没有同步锁,而Vector则有
add 方法不是原子性的操作,需要将数组扩充后,再放值,所以会出现问题
public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

以后在成员变量中尽量用Vector, 临时变量用ArrayList

你可能感兴趣的:(ArrayList)