线程安全的集合类--Java Concurrency In Practice C05读书笔记
[本文是我对Java Concurrency In Practice 5.1的归纳和总结. ?转载请注明作者和出处, ?如有谬误, 欢迎在评论中指正. ]
synchronized集合
java集合框架提供了多种synchronized集合, 比如Vector, HashTable, Collections的synchronizedXxx方法的返回值等.
synchronized集合是线程安全的, 但不是严格线程安全的. 根据JCIP第二章关于线程安全的定义--线程安全的类无需调用方进行额外的同步--synchronized集合是不满足该定义的. 如果我们将线程安全的定义放宽一些--单次调用对象的方法而无需调用方进行额外的同步, 这样synchronized集合就符合定义了.
为什么要加上单次调用的限定呢? 先看一个例子:
class SynchronizedList<E> extends SynchronizedCollection<E> implements List<E> {static final long serialVersionUID = -7754090372962971524L;final List<E> list;SynchronizedList(List<E> list) {super(list);this.list = list;}SynchronizedList(List<E> list, Object mutex) {super(list, mutex);this.list = list;}public boolean equals(Object o) {synchronized (mutex) {return list.equals(o);}}public int hashCode() {synchronized (mutex) {return list.hashCode();}}public E get(int index) {synchronized (mutex) {return list.get(index);}}// ....}这样的做法对性能有很大的影响, 比如多个线程的并发读操作并不会引起并发错误, 但在Synchronized集合中只能一个线程一个线程的读. 除此之外, javadoc明确要求使用Collections.synchronizedXxx包装一个集合对象后, 就不应该使用原有的集合, 因为使用原有的集合会破坏线程安全. 这样的线程安全依赖于约定, 是不可靠的.
jdk5及后续的版本增加了ConcurrentHashMap, CopyOnWriteArrayList, BlockingQueue, ConcurrentSkipListMap, ConcurrentSkipListSet等concurrent集合类.
?