2013-03-15 5 views
8

Я задал здесь вопрос об итерации через Vector, и на меня были ответы с некоторыми хорошими решениями. Но я прочитал еще один простой способ сделать это. Я хотел бы знать, если это хорошее решение.Итерация по синхронизированной коллекции

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

mapItems - это синхронизированная коллекция: Vector. Это делает повторение по безопасности Vector от ConcurrentModificationException?

+1

У вас есть правильный ответ, чтобы принять ?? – AmitG

ответ

3

Да, это сделает его безопасным от ConcurrentModificationException за счет всего, что является однопоточным.

2

Да, я считаю, что это предотвратит ConcurrentModificationException. Вы синхронизированы на Vector. Все методы на Vector, которые его модифицируют, также являются , что означает, что они также будут блокировать этот же объект. Таким образом, ни одна другая нить не может изменить Vector, пока вы повторяете ее.

Кроме того, вы не изменяете самостоятельно, пока вы итерируете его.

1

Возможно, вы захотите рассмотреть использование ReadWriteLock.

Для процессов, которые перебирают список без изменения его содержимого, получите блокировку чтения для общего ресурса ReentrantReadWriteLock. Это позволяет нескольким потокам иметь доступ для чтения к блокировке.

Для процессов, которые изменят список, приобретите блокировку записи в общей блокировке. Это предотвратит доступ всех других потоков к списку (даже для чтения), пока вы не освободите блокировку записи.

1

Это делает итерацию над безопасным вектором с ConcurrentModificationException?

ДА Это делает Перебор Вектор безопасности от ConcurrentModificationException .Если он не синхронизирован, то в том случае, если вы обращаетесь к Vector с помощью различных нитей и некоторые другие темы конструктивно изменяя вектор в любой время после создания итератора, итератор будет бросать ConcurrentModificationException. Рассмотрим работает этот код:

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(); 

    } 
} 

В моей системе он показывает следующий результат во время выполнения:

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) 

Но с другой стороны, если вы сделаете блок кода, содержащий Iterator для доступа к этому Vector синхронизирован используя mapItems в качестве блокировки, это предотвратит выполнение других методов, связанных с Vector, до тех пор, пока блок synchronized не будет завершен атомарно.

2

Просто синхронизация всей коллекции не помешает исключению ConcurrentModificationException. Это все равно будет выдавать CME

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

Если мы вызываем метод add внутри цикла while, то выдает исключение.

synchronized(mapItems) { 
    Iterator<MapItem> iterator = mapItems.iterator(); 
    while(iterator.hasNext()) 
     iterator.next(); 
     mapItems.add("Something"); // throws ConcurrentModificationException 
} 
Смежные вопросы