2017-11-25 22 views
0

次のコードブロックは、複数のスレッドがイテレータを使用してリストを変更しているので、プログラムをフェイル・ファスト・イベントにしてスローしますそれはOKを実行する、何が間違っている?なぜFailfastイベントとConcurrentModificationExceptionを得ることができないのですか?

import java.util.*; 
import java.util.concurrent.*; 


public class FastFailTest { 

private static List<String> list = new ArrayList<String>(); 
public static void main(String[] args) { 


    new ThreadOne().start(); 
    new ThreadTwo().start(); 
} 

private static void printAll() { 
    System.out.println(""); 

    String value = null; 
    Iterator iter = list.iterator(); 
    while(iter.hasNext()) { 
     value = (String)iter.next(); 
     System.out.print(value+", "); 
    } 
} 


private static class ThreadOne extends Thread { 
    public void run() { 
     int i = 0; 
     while (i<6) { 
      list.add(String.valueOf(i)); 
      printAll(); 
      i++; 
     } 
    } 
} 


private static class ThreadTwo extends Thread { 
    public void run() { 
     int i = 10; 
     while (i<16) { 
      list.add(String.valueOf(i)); 
      printAll(); 
      i++; 
     } 
    } 
} 

} 
+3

スレッドは、OSがその実行中のスケジュールやライフサイクルを管理しているので、プログラマが自分の実行順序に依存することができますいくつかのルーチンではありません。あなたの 'ThreadOne'のライフサイクルが短くて、' ThreadTwo'がOSによって実行される前に完全に実行されている可能性があります。したがって、同時実行は発生せず、例外もスローされません。共有リソースの同時実行と変更の可能性をいくらか増加させるために、スレッドで時間のかかるジョブを管理したい場合があります。 – STaefi

+2

これを取得する簡単な方法は 'for(String s:list)list.remove(s);'です。人々は(名前のために)スレッドと 'ConcurrentModificationException'を関連づけますが、ほとんどの場合、それは並行プログラミングによるものではありません。 – Kayaman

+1

例外は私に起こります。ここでの教訓は、マルチスレッドエラーは、実験/テストによって実際には見つけるのが難しいことです。正しいマルチスレッドコードを書くための最良の方法は、本当に注意深く、論理を通して考えることです。コードが壊れているとの前提から始めて、コードが壊れていないことを自分自身に証明してください。 – yshavit

答えて

1

コードを実行すると、時々私はCMEを取得していることがあります。

以下は、例外が発生したときのスタックトレースと出力です。 さて、両方のスレッドがデータを挿入しようとしているときに、両方のスレッドがリストにデータを挿入する時間が非常に短いため、時間が競合していないことが確実です。 私はコードを実行し、例外があります。

ThreadOneは[0,5]からの値のみを挿入でき、スレッド2は値[10,15]のみを挿入できるため、 最後の出力行は[0、10、11、12、13、14、スレッドの例外「スレッド0」java.util.ConcurrentModificationExceptionが]

私はThreadTwoは、リスト内の要素を挿入完了したことを信じていますが、一つは以下0

で一つだけの要素を追加したスレッドがスタックトレースです。

0, 0, 10, 10, 
0, 10, 11, 
0, 10, 11, 12, 
0, 10, 11, 12, 13, 
0, 10, 11, 12, 13, 14, 
0, 10, 11, 12, 13, 14, 15, Exception in thread "Thread-0" java.util.ConcurrentModificationException 
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901) 
    at java.util.ArrayList$Itr.next(ArrayList.java:851) 
    at com.failfast.FastFailTest.printAll(FastFailTest.java:23) 
    at com.failfast.FastFailTest.access$1(FastFailTest.java:17) 
    at com.failfast.FastFailTest$ThreadOne.run(FastFailTest.java:34) 
0

同時一覧については、次のクラスを使用し List newList = Collections.synchronizedList(new ArrayList());

Synchronized List

関連する問題