サーバーが既存の Collection の unmodifiableCollection をクライアントに与え、クライアントがそれを反復し始めるシナリオでは、同時にサーバー レベルで 1 つのスレッドが List を変更します。たとえば、その要素を削除します。これにより、クライアントに例外が発生しますか? はいの場合、それは何になりますか?リストの反復中に突然例外が発生した場合、クライアントにとって奇妙ではありませんか?
3 に答える
まず第一に、それはおそらくコレクションに依存します。これは、内部Collection
またはCollections
クラスのどこにも指定されていないためです。
第二に、それをテストすることは非常に簡単です。
public class CollectionModTest {
public static void main(String[] args) {
Collection<String> original = new HashSet<String>();
original.add("1");
original.add("2");
original.add("3");
original.add("4");
int counter= 5;
Collection<String> unmodifiable = Collections.unmodifiableCollection(original);
for (String val: unmodifiable) {
System.out.println(val);
original.add(""+counter);
counter++;
}
}
}
実装を使用する実装に置き換えるだけCollection
で、例外がスローされるかどうかを確認できます。
変更不可能なビューを作成したら、元のコレクション参照を失うことをお勧めします。そうすれば、コレクションを同時に変更することを心配する必要はありません。または、その後すぐに元のコレクションを変更する必要がある場合は、コレクションのコピーを作成して、それを反復処理することができます。元のコレクションは、どこでも同時に変更できます。クリティカル セクションは、新しい (コピー) コレクションの作成と同じくらい短くなります。
クライアントは を変更できないためunmodifiableCollection
、 では削除できませんunmodifiableCollection
。
まず、それは何であるかに依存しclient
ます。クライアントがネットワークまたはその他の手段を介してコレクションを受信した場合、サーバー側コレクションの変更はクライアントのコレクションを変更しません。これは、別の JVM 上の別のオブジェクトであるためです。
サーバーとクライアントの両方が同じ JVM 内の同じオブジェクトを参照している場合、クライアントの反復方法によって異なります。
クライアントがこれを行う場合:
for(int i = 0;i < col.size();i++) { col.get(i);}
エラーは発生しません。
クライアントが Iterator を使用する場合、またはクライアントが Iterator を直接使用する場合は、ほとんどの場合、ベスト エフォート ベースでfor(Object o : col)
取得できます。ConcurrentModificationException