为什么SynchronizedList的listIterator需要用户进行外部同步?

时间:2012-07-04 06:53:04

标签: java multithreading synchronization java.util.concurrent

请参考以下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()方法那样被互斥锁保护?他们为什么要设计它以便需要用户进行外部同步?

3 个答案:

答案 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,另外两个是ArrayListLinkedList

一个原因是,如果我们正在处理Vectors,那么synchronization上不需要Vector,因为它已经是线程安全的,但如果我们使用ArrayList并且LinkedList然后我们需要同步这些列表

其他原因是我们可以在SynchronizedList应用中使用Single-Threaded类,如果他们将listIterator()设为Synchronized那么这会被不必要的thread-safety打中甚至在single-threaded环境中。