2017-12-18 12 views
0

私はこの概念をいくつかのチュートリアルから理解していましたが、あるスレッドがリストを反復している間、他のスレッドは基になるリストを変更することができ、ConcurrentModificationException(CME)を取得できません。 CMEを入手してください。CopyOnWriteArrayList(cowal)

しかし、次のプログラムではスレッド(メインスレッド)は1つのみですが、CMEを取得しています。なぜですか?

イテレータですか?

ALをCOWALに置き換えても例外はありませんが、要素 "D"も持っていません。なぜですか?イテレータが作成された後、あなたがリスト構造(要素の追加または削除)を変更しているライン

l.add("d"); 

ので

AL<String> l=new AL<>(); 
l.add("a"); 
l.add("b"); 
l.add("c"); 
Iterator<String> itr=l.iterator(); 
l.add("d"); 
while(itr.hasNext()) 
{ 
String s=itr.next(); 
Sop(s); 
} 
+0

私すでにやった...あなたはそれの上にマウスを置くならば、これはネットの概念ではなく、JVMのものであることを説明し、「コンカレント・コレクション」 –

+0

。例外を取得する理由は、イテレータをすでに取得した後にコレクション(AL)を変更するためです。ここに含まれるスレッドの数は関係ありません。 – StuartLC

+0

タグを変更しました.netの概念.. –

答えて

1

エラーがあります。

あなたは内部的には、(ArrayListの中に追加または削除)任意の構造のリストに加えられた変更をチェックしている

itr.next(); 

を呼び出していると、一つの要素が追加され、したがって、配列リストのサイズが変更されたことがあること、それは創設..だからあなたはその例外を手に入れているのです。 ArrayListのクラスで

あなたはこのエラーを取得していないでしょうイテレータを作成する前に、またはイテレータを使用した後、あなたが

以下

は、次の(のコード..ですその要素を追加する場合)。

 @SuppressWarnings("unchecked") 
    public E next() { 
     checkForComodification(); 
     ...... 
     return (E) elementData[lastRet = i]; 
    } 

    final void checkForComodification() { 
     if (modCount != expectedModCount) 
      throw new ConcurrentModificationException(); 
    } 
1

ArrayListのイテレータはフェイルファスト設計によりあるので、あなたはConcurrentModificationExceptionを得ています。つまり、イテレータが作成された後に、ArrayList(要素の追加または削除)がに変更された場合は、ConcurrentModificationExceptionがスローされます。

あなたは例外ログ文を確認した場合は、リストからイテレータを作成しながらコピーをそれmodCount変数を使用してArrayListの大きさのcheckForComodification()メソッドを呼び出すことにより、修正のためのイテレータチェックのnext()方法のでitr.next()法によりラインString s=itr.next();でスローされます。

今、あなたはCopyOnWriteArrayListは、すべての変更操作は、追加、削除、セットを新しい内部配列をコピーすることによって実現されている好きれるArrayListスレッドセーフvarientのであるため、この例外はある取得されていませんCopyOnWriteArrayListについての話をすることができます古い配列を新しく作成したものに置き換えます。

リストからイテレータを取得すると、配列の参照が保持されます。リストに要素を追加すると、リストの配列はすべて新しいものになります。イテレータはまだ古い配列を指しています。

文で新しく追加された要素l.add("d");がコンソールに表示されないことに気が付いたことがあります。しかし、あなたがリスト全体を印刷するなら、それはそこにあります。ここで

CopyOnWriteArrayListを使用して、サンプルコードです:

List<String> l = new CopyOnWriteArrayList<>(); 
    l.add("a"); 
    l.add("b"); 
    l.add("c"); 
    Iterator<String> itr = l.iterator(); 
    l.add("d"); 
    while (itr.hasNext()) { 
     String s = itr.next(); 
     System.out.println(s); 
    } 
    System.out.println(l); 

出力が生産されている:

a 
b 
c 
[a, b, c, d] 

は、この情報がお役に立てば幸いです。 お楽しみください:)

関連する問題