2013-03-15 7 views
8

Ho posto qui una domanda sull'iterazione su un Vector e mi è stato risposto con alcune buone soluzioni. Ma ho letto di un altro modo più semplice per farlo. Mi piacerebbe sapere se è una buona soluzione.Iterazione su collezione sincronizzata

synchronized(mapItems) { 
    Iterator<MapItem> iterator = mapItems.iterator(); 
    while(iterator.hasNext()) 
     iterator.next().draw(g); 
} 

mapItems è una raccolta sincronizzata: Vector. È possibile rendere l'iterazione su Vector sicuro da ConcurrentModificationException?

+1

hai qualche risposta corretta da accettare ?? – AmitG

risposta

3

Sì, lo rende sicuro da ConcurrentModificationException a scapito di tutto essenzialmente essendo single-threaded.

2

Sì, credo che ciò impedirà uno ConcurrentModificationException. Si sta effettuando la sincronizzazione su Vector. Tutti i metodi su Vector che lo modificano sono anche synchronized, il che significa che avrebbero anche bloccato lo stesso oggetto. Quindi nessun altro thread potrebbe cambiare il Vector mentre lo stai iterando.

Inoltre, non si sta modificando lo Vector mentre si sta iterando su di esso.

1

Si consiglia di prendere in considerazione l'utilizzo di ReadWriteLock.

Per i processi che eseguono l'iterazione nell'elenco senza modificarne il contenuto, ottenere un blocco di lettura sul ReentrantReadWriteLock condiviso. Ciò consente a più thread di avere accesso in lettura al blocco.

Per i processi che modificano l'elenco, acquisire il blocco di scrittura sul blocco condiviso. Ciò impedirà a tutti gli altri thread di accedere all'elenco (anche di sola lettura) finché non si rilascia il blocco di scrittura.

1

E 'l'iterazione sulla cassaforte Vector da ConcurrentModificationException?

SI rende l'iterare su Vector salvo da ConcurrentModificationException .If non è sincronizzato in quel caso, se si accede il vettore tramite vari fili e qualche altro thread è strutturalmente modificando il vettore in qualsiasi dopo che l'iteratore è stato creato, l'iteratore genererà ConcurrentModificationException. Considerare l'esecuzione di questo codice:

import java.util.*; 
class VVector 
{ 
    static Vector<Integer> mapItems = new Vector<Integer>(); 
    static 
    { 
     for (int i = 0 ; i < 200 ; i++) 
     { 
      mapItems.add(i); 
     } 
    } 
    public static void readVector() 
    { 
     Iterator<Integer> iterator = mapItems.iterator(); 
     try 
     { 
      while(iterator.hasNext()) 
      { 
       System.out.print(iterator.next() + "\t"); 
      } 
     } 
     catch (Exception ex){ex.printStackTrace();System.exit(0);} 
    } 
    public static void main(String[] args) 
    { 
     VVector v = new VVector(); 
     Thread th = new Thread(new Runnable() 
     { 
      public void run() 
      { 
       int counter = 0; 
       while (true) 
       { 
        mapItems.add(345); 
        counter++; 
        if (counter == 100) 
        { 
         break; 
        } 
       } 
      } 
     }); 
     th.start(); 
     v.readVector(); 

    } 
} 

A mio sistema sta mostrando seguente output, mentre l'esecuzione:

0  1  2  3  4  5  6  7  8  9 
java.util.ConcurrentModificationException 
     at java.util.AbstractList$Itr.checkForComodification(Unknown Source) 
     at java.util.AbstractList$Itr.next(Unknown Source) 
     at VVector.readVector(VVector.java:19) 
     at VVector.main(VVector.java:38) 

Ma d'altra parte se si effettua il blocco di codice contenente Iterator ad accedere a tale Vector sincronizzato utilizzando mapItems come blocco, impedirà l'esecuzione di altri metodi relativi a Vector finché il blocco synchronized non viene completato in modo atomico.

2

La semplice sincronizzazione dell'intera raccolta non impedisce una ConcurrentModificationException. Ciò continuerà a generare un CME

synchronized(mapItems) { 
    for(MapItem item : mapsItems){ 
     mapItems.add(new MapItem()); 
    } 
} 
0

se invochiamo il metodo add all'interno del ciclo while genera un'eccezione.

synchronized(mapItems) { 
    Iterator<MapItem> iterator = mapItems.iterator(); 
    while(iterator.hasNext()) 
     iterator.next(); 
     mapItems.add("Something"); // throws ConcurrentModificationException 
}