请参考以下java源代码:
static class SynchronizedList<E>
extends SynchronizedCollection<E>
implements List<E> {
final List<E> list;
public boolean equals(Object o) {
synchronized (mutex) {return list.equals(o);}
}
public int hashCode() {
synchronized (mutex) {return list.hashCode();}
}
public ListIterator<E> listIterator() {
return list.listIterator(); //Must be manually synched by user
}
我的问题是为什么 listIterator() 不像 hashcode() 和 equals() 方法那样受到互斥锁的保护?为什么他们设计它需要用户进行外部同步?
ListIterator的主要用途不是获取它,而是迭代它以访问列表中的单个元素。这是一个有状态的操作,完全由客户端完成,而不是由类SynchronizedList
完成。另一方面,方法equals()
和hashCode()
完全在SynchronizedList
内计算,不需要客户端做太多期望获取返回值。正如 user1252434 指出的那样,同步获取迭代器的方法并没有多大帮助。
ListIterator 是使用客户端锁定作为策略以确保在原始类无法提供同步时进行同步的典型示例。
如果您建议:
public ListIterator<E> listIterator() {
synchronized(mutex) { return list.listIterator(); }
}
这无济于事。
您将同步迭代器本身的创建,这可能有助于解决一些问题。但您不会同步迭代器的使用。当您持有迭代器时,仍然可以对列表进行更改,并且 - 取决于实现 - 甚至可能导致它失败,因为列表可能暂时处于无效的内部状态。
可能有两个原因。
我们有三种不同的List
实现接口。一个是Vector
,另外两个是ArrayList
和LinkedList
。
一个原因是,如果我们正在处理Vectors
那么Vector
绝对不需要synchronization
,因为它已经是线程安全的,但是如果我们使用 ArrayList
和 LinkedList
那么我们需要同步这些列表
另一个原因是我们可以在应用程序中使用SynchronizedList
类Single-Threaded
如果他们会按照Synchronized
进行listIterator()
那么即使在single-threaded
环境中,这也是不必要的thread-safety
的性能影响。