大家都知道Vector是线程安全的,ArrayList是不安全的, 现在测试下ArrayList怎么个不安全法
运行多次可以发现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
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