ArrayList,Vectorスレッドセキュリティテスト


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(10);
			} 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();

	}
}

結果:
hello3start hello3 list size is 1 hello1start hello1 list size is 2 hello2start hello2 list size is 3hello3 list size is 4 hello1 list size is 5hello2 list size is 4 hello3 list size is 6 hello1 list size is 8 hello2 list size is 7hello1 list size is 9 hello3 list size is 10hello2 list size is 9
 
12回追加しましたが、sizeは10しかなく、安全ではありません.
 
スレッドセキュリティと呼ばれるVectorに変更:
import java.util.Vector;

// Runnable 
public class HelloThread implements Runnable {
	String name;
	Vector<String> v;

	HelloThread(String name, Vector<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 + " vector size is " + v.size());

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

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

		Vector<String> v = new Vector<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();
	}
}

結果:
hello1start hello1 vector size is 1 hello2start hello2 vector size is 2 hello3start hello3 vector size is 3 hello1 vector size is 4 hello2 vector size is 5 hello3 vector size is 6 hello1 vector size is 7 hello2 vector size is 8 hello3 vector size is 9 hello1 vector size is 10 hello2 vector size is 11 hello3 vector size is 12 hello1 vector size is 13hello3 vector size is 15 hello2 vector size is 15 hello1 vector size is 16
 
スレッドが安全でない現象も発生しましたか?いいえ
 
これはスレッドが安全ではなく、16回追加され、sizeは16で、ちょうどスレッドの安全な表現で、2つのスレッドがaddが終わってから調整されたsize()にすぎないので、いずれも15で、14をスキップしました.
 
以上のようなプログラムが何度か試して出てきましたが、またVectorのthread-safetyについて
All Vector methods are synchronized themselves, so as long as you are only synchronizing around a single method, your own synchronization is not necessary. If you have several method calls, which depend on each other, e.g. something like vec.get(vec.size()-2) to get the second last element, you have to use your own synchronization since otherwise, the vector may change between vec.size() and vec.get().
 
すべてのVectorメソッドはそれら自身にとってsynchronizedであるため、単一のメソッドを同期するだけで、自分で追加した同期措置は必要ありません.いくつかの方法が呼び出す必要があり、vecなどの相互依存がある場合.get(vec.size(-2)は、最後から2番目の要素を得るには、自分の同期措置を加えなければならない.そうしないとvectorがvecにいる可能性があるからだ.size()とvec.get()間で変更