1

次の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()メソッドのようにミューテックスによって保護されていないのですか?なぜ彼らはそれがユーザーによる外部同期を必要とするようにそれを設計したのですか?

4

3 に答える 3

2

ListIterator の主な使用法は、それを取得することではなく、リスト内の個々の要素を訪問するために実際に反復することです。これはステートフルな操作であり、クラスではなくクライアントによって完全に行われますSynchronizedList。一方、メソッドequals()とメソッドhashCode()は完全に 内で計算されSynchronizedList、返された値を取得するためにクライアントが多くのことを行う必要はありません。user1252434が指摘したように、メソッドを同期してイテレータを取得することはあまり役に立ちません。

ListIterator は、元のクラスがこれを提供できない場合に同期を確保するための戦略としてクライアント側のロックを使用する典型的な例です。

于 2012-07-04T08:35:11.160 に答える
2

あなたが提案する場合:

public ListIterator<E> listIterator() {
    synchronized(mutex) { return list.listIterator(); }
}

それはあまり役に立ちません。

イテレータ自体の作成を同期すると、いくつかの問題を回避できる場合があります。ただし、反復子の使用を同期しません。リストが一時的に無効な内部状態にある可能性があるため、イテレータを保持している間でもリストに変更を加えることができ、実装によっては失敗することさえあります。

于 2012-07-04T07:56:36.460 に答える
0

2 つの理由が考えられます。

インターフェイスの 3 つの異なる実装がありListます。1 つはVectorで、他の 2 つはArrayListLinkedListです。

理由の 1 つは、対処している場合は、すでにスレッドセーフであるためVectors、反抗的synchronizationに必要ありませんが、使用していて、これらのリストを同期する必要がある場合です。VectorArrayListLinkedList

他の理由は、アプリケーションSynchronizedList でクラスを使用できるためです。これは、環境でも不必要にパフォーマンスが低下するためです。Single-ThreadedlistIterator()Synchronizedthread-safetysingle-threaded

于 2012-07-04T07:25:27.140 に答える