Iterate over a synchronized collection

I asked here a question about iterating over Vector , and there were answers to me with some good solutions. But I read another easy way to do this. I would like to know if this is a good solution.

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

mapItems is a synchronized collection: Vector. Does it iterate over Vector security from ConcurrentModificationException ?

+8
java multithreading synchronized vector
source share
6 answers

Yes, this will make it safe from ConcurrentModificationException due to everything that is essentially single-threaded.

+3
source share

Yes, I believe this will prevent a ConcurrentModificationException . You are syncing to Vector . All Vector methods that change it are also synchronized , which means that they also block the same object. Thus, no other thread can change Vector while you repeat it.

In addition, you do not modify Vector yourself while you repeat it.

+2
source share

Just synchronizing the entire collection will not prevent a ConcurrentModificationException. It will still cause CME

 synchronized(mapItems) { for(MapItem item : mapsItems){ mapItems.add(new MapItem()); } } 
+2
source share

You might want to use ReadWriteLock.

For processes that iterate over a list without changing its contents, get a read lock on the shared ReentrantReadWriteLock. This allows multiple threads to have read access to the lock.

For processes that will modify the list, acquire a write lock in the general lock. This will prevent all other threads from accessing the list (even for reading) until you release the write lock.

+1
source share

Does it iterate over the security of Vector ConcurrentModificationException?

YES . It does an iteration over Vector security with a ConcurrentModificationException . If it is not synchronized, then in this case, if you access Vector through various threads, and some other thread structures the Vector at any time after creating the iterator, the iterator will throw a ConcurrentModificationException . Try running this code:

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

On my system, the following output is displayed at runtime:

 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) 

But on the other hand, if you create a code block containing Iterator to access this Vector , synchronized with mapItems as a lock, this will prevent other methods related to Vector from being executed until synchronized completes atomically.

+1
source share

if we call the add method inside the while loop and throw an exception.

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

All Articles