大可制作:QQ群:31564239(asp|jsp|php|mysql)

Java Gossip: 容器类的线程安全(Thread-safe)

容器类默认没有考虑线程安全问题,您必须自行实现同步以确保共用数据在多线程存取下不会出错,例如若您使用 List对象时,您可以这样实现:
// arraylist指向一个ArrayList的一个实例
synchronized(arraylist) {
    arraylist.add(new SomeClass());
}
 
事实上,您也可以使用Collections的synchronizedXXX()等方法来传回一个同步化的容器对象,例如传回一个同步化的List:
List list = Collections.synchronizedList(new ArrayList());
 
以这种方式返回的List对象,在存取数据时,会进行同步化的工作,不过在您使用Iterator遍访对象时,您仍必须实现同步化,因为这样的List使用iterator()方法返回的Iterator对象,并没有保证线程安全(Thread-safe),一个实现遍访的例子如下:
List list = Collections.synchronizedList(new ArrayList());
      ...
synchronized(list) {
      Iterator i = list.iterator();
      while (i.hasNext())
          foo(i.next());
}
 
在J2SE 5.0之后,新增了 java.util.concurrent 这个 package,当中包括了一些确保线程安全的 Collection 类,例如 ConcurrentHashMapCopyOnWriteArrayListCopyOnWriteArraySet等等,这些新增的 Collection 类基本行为与先前介绍的Map、List、Set等对象是相同的,所不同的是增加了同步化的功能,而且依对象的特性不同而有不同的同步化实现,以确保效率与安全性。

例如ConcurrentHashMap,它针对Hash Table中不同的区段(segment)进行同步化,而不是对整个对象进行同步化,默认上HashMap有16个区段,当有线程在存取第一个区段时, 第一个区域进入同步化,然而另一个线程仍可以存取第一个区段以外的区段,而不用等待第一个线程存取完成,所以与同步化整个对象来说,新增的这些同步化 对象,在效率与安全性上取得了较好的平衡。