请参考以下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()方法那样被互斥锁保护?他们为什么要设计它以便需要用户进行外部同步?
答案 0 :(得分:2)
如果你建议:
public ListIterator<E> listIterator() {
synchronized(mutex) { return list.listIterator(); }
}
这无济于事。
您将同步迭代器本身的创建,这可能有助于解决一些问题。但是你不会同步迭代器的 use 。当你持有迭代器时仍然可以对列表进行更改,并且 - 实现依赖 - 甚至可能导致它失败,因为列表可能暂时处于无效的内部状态。
答案 1 :(得分:2)
ListIterator的主要用途不是获取它,而是实际迭代它以访问列表中的各个元素。这是一个有状态操作,完全由客户端完成,而不是由类SynchronizedList
完成。另一方面,方法equals()
和hashCode()
完全在SynchronizedList
内计算,并且不要求客户端期望获取返回的值。 user1252434指出,将方法同步到获取迭代器并没有多大帮助。
ListIterator是一个典型的例子,它使用客户端锁定作为策略,以确保在原始类无法提供此功能时进行同步。
答案 2 :(得分:0)
可能有两个原因。
我们有三种不同的List
接口实现。一个是Vector
,另外两个是ArrayList
和LinkedList
。
一个原因是,如果我们正在处理Vectors
,那么synchronization
上不需要Vector
,因为它已经是线程安全的,但如果我们使用ArrayList
并且LinkedList
然后我们需要同步这些列表
其他原因是我们可以在SynchronizedList
应用中使用Single-Threaded
类,如果他们将listIterator()
设为Synchronized
那么这会被不必要的thread-safety
打中甚至在single-threaded
环境中。