2017-03-03 3 views
0

Hier ist mein Test:Warum ConcurrentModificationException in Vektor

public static List<String> list =new Vector<String>(); 
@Test 
public void main(){ 
    new ThreadOne().start(); 
    new ThreadTwo().start(); 
} 
public static void printAll(){ 
    String valueString= null; 
    Iterator<String> iterator=list.iterator(); 
    while(iterator.hasNext()){ 
     valueString = (String) iterator.next(); 
     System.out.print(valueString+","); 
    } 
    System.out.println("\n"); 
} 
public static class ThreadOne extends Thread{ 
    public void run(){ 
     int i=10; 
     while(i<100000){ 
      list.add(String.valueOf(i)); 
      printAll(); 
      i++; 
     } 
    } 

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

     } 
    } 

} 

und ich sah in den Quellcode über den Iterator in Vector.class:

public synchronized Iterator<E> iterator() { 
    return new Itr(); 
} 

/** 
* An optimized version of AbstractList.Itr 
*/ 
private class Itr implements Iterator<E> { 
    int cursor;  // index of next element to return 
    int lastRet = -1; // index of last element returned; -1 if no such 
    int expectedModCount = modCount; 

    public boolean hasNext() { 
     // Racy but within spec, since modifications are checked 
     // within or after synchronization in next/previous 
     return cursor != elementCount; 
    } 

    public E next() { 
     synchronized (Vector.this) { 
      checkForComodification(); 
      int i = cursor; 
      if (i >= elementCount) 
       throw new NoSuchElementException(); 
      cursor = i + 1; 
      return elementData(lastRet = i); 
     } 
    } 

ich über it.When die confuced wurde Programm ausgeführt iterator.next(), der Vektor Objekt wurde gesperrt, Während das Programm die list.add() ausgeführt, der Vektor wurde auch gesperrt. Die Variable "expectedModCount" entspricht immer "modCount". Warum tritt die ConcurrentModificationException auf?

+2

Es löst eine Ausnahme aus, weil es * zwischen * Aufrufen von 'next()' geändert wurde. Sie müssten die gesamte Iteration synchronisieren, um sie threadsicher zu machen. Überraschend ist, dass dies nicht explizit in der Klasse "Vector" dokumentiert ist, wie es für ['Collections.synchronizedList()'] (https://docs.oracle.com/javase/8/docs/api) der Fall ist /java/util/Collections.html#synchronizedList-java.util.List-). – shmosel

+1

@smossel Wenn du das als Antwort postest, werde ich es aufwerten. –

+0

können Sie mehr hier http://www.journaldev.com/378/java-util-concurrentmodificationexception überprüfen, die Ihnen mehr klare Idee gibt, wie man das repariert –

Antwort

0

Die nächste Methode des Iterators ist die Synchronisierung. Das bedeutet, dass die Sperre nach dem Lesen jedes Elements aufgehoben wird und dann beim Lesen des nächsten Elements die Sperre erfasst wird. Zwischen den Aufrufen von "next" besteht immer noch die Möglichkeit, dass sich der Inhalt des Vektors so ändert, dass die ConcurrentModificationException ausgelöst wird.

+0

ob ich Iterator erstelle iterator = list.iterator(); – ollamo

+0

es ist, wenn Sie iterator.next(), der Wert wird nicht aktualisiert, und Thread ist nicht sicher, was das Problem verursacht –

+0

Ok, ist das richtig: wenn Thread eins Iterator erstellen iterator = list.iterator() ; der expectedCount = modCount.But Thread zwei ändern modCount. Also, wenn Thread 1 Iterator .next() durchgeführt. Das Problem trat auf ???? – ollamo

Verwandte Themen