1

ArrayListが同期していないために動作していない複数のスレッドによって操作されていたArrayListがありました。私は教授の指示に従ってリストをVectorに切り替えました。ベクトルは同期されていますが、同期に関する例外がスローされています。VectorがConcurrentModificationExceptionをスローしますが、同期しています

なぜこのようなことが起こりますか、コード内で並行処理の例外を避けるにはどうすればよいですか?私は何かが働くまで遊ぶことはしたくない、最高のことをしたい。ありがとう!

例外:

Exception in thread "Thread-3" java.util.ConcurrentModificationException 
    at java.util.Vector$Itr.checkForComodification(Vector.java:1184) 
    at java.util.Vector$Itr.next(Vector.java:1137) 
    at BytePe4D$ReadInts.run(BytePe4D.java:64) 

はコード:

import java.io.*; 
import java.util.Vector; 

public class BytePe4D { 
    private Vector<Integer> numbers; 

    public static void main(String[] args) { 
     new BytePe4D(); 
    } 

    public BytePe4D() { 
     // Create ArrayList and reset sum 
     numbers = new Vector<Integer>(); 

     // Call addInts 8 times, with filenames integer1.dat through integer8.dat 
     for (int i = 1; i <= 8; i++) { 
      File file = new File("PE Data/integer" + i + ".dat"); 
      ReadInts thread = new ReadInts(file); 
      thread.start(); 
     } 
    } 

    /** Represents a Thread instance */ 
    class ReadInts extends Thread { 
     File file; 

     public ReadInts(File _file) { 
      file = _file; 
     } 

     @Override 
     public void run() { 
      int count = 0; // track number of records read 
      int sum = 0; 

      try { 
       // Open stream to binary data file integer1.dat 
       FileInputStream in = new FileInputStream(file); 
       // Buffer the stream 
       BufferedInputStream bin = new BufferedInputStream(in); 
       // Access the primitive data 
       DataInputStream din = new DataInputStream(bin); 

       try { 
        // Read file until end reached 
        while (true) { 
         numbers.add(din.readInt()); 
         count++; 
        } 
       } catch (EOFException eof) { 
        // System.out.println("End of file reached."); 
       } finally { 
        // Close streams 
        din.close(); 
       } 
      } catch (FileNotFoundException fnf) { 
       System.out.println("File does not exist: " + file.getName()); 
       return; 
      } catch (IOException ioe) { 
       ioe.printStackTrace(); 
      } 

      // Calculate sum of numbers read 
      for (int num : numbers) { 
       sum += num; 
      } 

      // Write info 
      System.out.println(
       String.format("%s%s%-5s%s%-8d%-5s%s%-12d%-5s%s%d", 
       "Filename = ", file.getName(), "", 
       "Count = ", count, "", 
       "Sum = ", sum, "", 
       "In List = ", numbers.size())); 
     } 
    } 

} 
+3

同期は、 'Iterator'を保護しません。 – Andreas

+1

合計は –

+0

を計算しようとするとベクトルが変更されるので、その部分の周りに同期ブロックが必要ですか? – briennakh

答えて

3

ベクトルが構造反復子 の作成後に、反復子自体のremove以外の方法で、いつでも変更または メソッドを追加している場合、反復子はConcurrentModificationExceptionをスローします。別のベクトルがそれを反復している間1つのスレッドが(要素を追加することによって)ベクトルを変更するときに

for (int num : numbers) { 
    sum += num; 
} 

- あなたはConcurrentModificationException

が表示されます:

次のコードでは、カバーの下にイテレータを作成します

これを解決するためのさまざまなオプションがあります。ファイルから別のベクトルに読み込む方法と、読み込みが完了したらnumbersに割り当てます(割り当てはアトミックな操作です)。変更が他のスレッドに見えるようにするには、numbersvolatileと宣言する必要があります。

+0

ありがとうございました。各スレッドには、スレッドが完了した後にメインのVectorに追加される独自のArrayListが含まれています。イテレータはこのArrayListにアクセスするため、並行性の問題はありません。 – briennakh

5

あなたのコードが間違っているようです。

各スレッドが個々のファイルからのレコードの合計を計算する場合、共有ベクトルが必要な理由はわかりません。一方、すべてのファイルからのレコードの合計を計算する場合は、すべてのスレッドが完了した後に行う必要があります。

スレッドのベクトルを作成して各ファイルの合計を計算するか、メインスレッドですべてのスレッドが完了するのを待ってからすべてのファイルの合計を計算するか。 docsから

関連する問題