ArrayList vs Vector

2157 ワード

みんなはすべて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