众所周知,java中vector与hashtable是线程安全的,主要是java对两者的操作都加上了synchronized,也就是上锁了。因此 在vector与hashtable的操作是不会出现问题。但是有一种情况:就是将一个hashtable copy到另一个hashtable时,假如使用putAll方法的花,会抛出一个 java.util.ConcurrentModificationException异常。先上代码:
TestSync.java
public class TestSync {
/** * main(这里用一句话描述这个方法的作用) * (这里描述这个方法适用条件 – 可选) * @param args * @return void * @exception * @since 1.0.0 */ public static void main(String[] args) { Map<Integer,User> list = new Hashtable<Integer, User>(); List<User> vec = new Vector<User>(); TestThread thread = new TestThread(); thread.start(); int i = 0; while(i<1000) { i++; System.out.println("iiiiiiiiii=------------" + i); list.clear(); vec.clear();
//vector与hashtable是线程安全的 ,putAll方法中两个集合实现不一样 vec.addAll(Constans.USERVEC); // synchronized (Constans.USERLIST) // { list.putAll(Constans.USERLIST); // } System.out.println("--------" + list.size()); System.out.println("--------" + vec.size()); } System.out.println("Over---------------------------------------------"); }
}
class Constans { public static Map<Integer,User> USERLIST = new Hashtable<Integer, User>(); public static List<User> USERVEC = new Vector<User>(); }
class TestThread extends Thread { @Override public void run() { for(int i=0;i<100000;i++) { User user = new User(); user.setId(i); user.setName("name" + i); if(!Constans.USERLIST.containsKey(i)) { Constans.USERLIST.put(i,user); Constans.USERVEC.add(user); }
} System.out.println("线程结束------------"); }
}
当我们将
//synchronized (Constans.USERLIST) // { list.putAll(Constans.USERLIST); // }
不使用同步时,就回抛出异常。是由于Constans.USERLIST不同步,而不是putAll方法不安全。
而Vector与Hashtable不同的是Vector的addAll方法不使用同步也可以正常运行,那是由于Vector的addAll与Hashtable的putAll方法不同,Vector的addAll会将参数先copy一份,因此不会产生异常。
User.java
public class User { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; }
}
写的不好,大家原谅。 |