1.前言
Java集合框架中的Vector集合通过对可能引发线程安全问题的方法(例如:add()、remove()、size()等等)加synchronized关键字实现了线程安全,但这种实现仅能在一定程度上减少多线程并发操作下出现问题的可能性,例如下面的情况就可能会出现线程不安全问题。
Vector<String> vector = new Vector<>();
......
......
for(int i = 0; i < vector.size(); i++){
//当前线程时间片到期,当前线程被挂起
...... //其他线程删除vector内的元素
//当前线程再次获取到时间片,但vector内的元素已被其他线程删除,可能引发数组越界异常
System.out.println(vector.get(i));
}
2.案例演示
基于以上的思路,可以通过以下代码来验证Vector的线程不安全问题
import java.util.Vector;
public class TestVectorNoSafe {
private static Vector<Integer> vector = new Vector<>();
public static void main(String[] args) {
while (true) {
for (int i = 0; i < 10; i++)
vector.add(i);
Thread removeThread = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < vector.size(); i++) {
Thread.yield();
vector.remove(i);
}
}
});
Thread printThread = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < vector.size(); i++) {
Thread.yield();
System.out.println(vector.get(i));
}
}
});
removeThread.start();
printThread.start();
while (Thread.activeCount() > 20) ;//防止线程太多计算机卡死
}
}
}
上面的代码运行后,就会出现数组越界异常
3.结论
Vector所谓的线程安全是指调用Vector类的成员方法时,其他线程不能再访问该Vector对象。但是在调用两个Vector成员方法时,当前线程有可能再完成第一个方法后时间片到期,这时其他线程可以访问该Vector对象,造成调用第二个成员方法的结果可能与预想结果不同。这时为保证线程安全,需要加synchronized。