Ever since the initial release of Java, the Vector and Hashtable classes provided thread-safe
implementations of a dynamic array and a hash table. In Java SE 1.2, these classes were
declared obsolete and replaced by the ArrayList and HashMap classes. Those classes are not
thread-safe. Instead, a different mechanism is supplied in the collections library. Any
collection class can be made thread-safe by means of a synchronization wrapper:
自从java的最初版以来,Vector和HashTable类提供了一个线程安全的动态数组和hash table的实现。但从java se 1.2开始,这些类被声明为"废弃的",替换它们的是ArrayList和HashMap类,这些类不是线程安全的。在集合框架中加入了另外一种 a synchronization wrapper的机制来实现线程安全
List<E> synchArrayList = Collections.synchronizedList(new ArrayList<E>());
Map<K, V> synchHashMap = Collections.synchronizedMap(new HashMap<K, V>());
The methods of the resulting collections are protected by a lock, providing thread-safe
access.
synchArrayList和synchHashMap被一个锁保护,提供线程安全的访问
You should make sure that no thread accesses the data structure through the original
unsynchronized methods. The easiest way to ensure this is not to save any reference to
the original object. Simply construct a collection and immediately pass it to the wrapper,
as we did in our examples.
你要确保没有其他的线程可以访问到原始未同步的集合类的引用。最简单的方法是不要保存任何原始集合类实例的引用,
只是简单地创始一个集合并立即把它传给the wrapper---就如同上面的例子
You still need to use “client-side” locking if you want to iterate over the collection while
another thread has the opportunity to mutate it:
synchronized (synchHashMap)
{
Iterator<K> iter = synchHashMap.keySet().iterator();
while (iter.hasNext()) . . .;
}
You must use the same code if you use a “for each” loop because the loop uses an itera-
tor. Note that the iterator actually fails with a ConcurrentModificationException if another
thread mutates the collection while the iteration is in progress. The synchronization is
still required so that the concurrent modification can be reliably detected.
如果你用到了iterator()方法或for each循环在一个线程中,那么你仍然要使用额外的客户端同步,例如使用synchronized关键字
,否则会产生一个ConcurrentModificationException
You are usually better off using the collections defined in the java.util.concurrent package
instead of the synchronization wrappers. In particular, the ConcurrentHashMap map has been
carefully implemented so that multiple threads can access it without blocking each other,
provided they access different buckets. One exception is an array list that is frequently
mutated. In that case, a synchronized ArrayList can outperform a CopyOnWriteArrayList.