0

I want to let a single thread wait for another one to finish writing on a Hashmap but I always get a java.util.ConcurrentModificationException, eventhough I synchronized the method.

Here is my Code:

HashMap<Page, Integer> prebuffer = new HashMap<Page, Integer>();
Map<Page,Integer> buffer = Collections.synchronizedMap(prebuffer);

private synchronized void bufferContaining(int pageid) {
    synchronized (buffer) {
        if (buffer.size() > 1) {
            for (Map.Entry<Page, Integer> entry : buffer.entrySet()) {
                Page page = entry.getKey();
                int taIds = entry.getValue();
                if (page.pid == pageid) {
                    buffer.remove(page, new Integer(taIds));
                }
            }
        }
    }
}

Thank you very much for your help! :)

Ali Pacman
  • 719
  • 7
  • 12
  • Use a [`ConcurrentHashMap`](https://docs.oracle.com/javase/10/docs/api/java/util/concurrent/ConcurrentHashMap.html). – Turing85 Jun 10 '18 at 17:43

2 Answers2

1

The problem is not related to the synchronize but to the fact that you are removing elements from the collection in which you are iterating, the buffer map.

You have few approaches to follow:

  • Remember the items to delete, and delete them afterwards
  • Use iterator to move and directly remove from the map
NiVeR
  • 9,644
  • 4
  • 30
  • 35
0

This is not a synchronization problem. This will occur if the underlying collection that is being iterated over is modified by anything other than the Iterator itself.

Iterator it = map.entrySet().iterator();
while (it.hasNext())
{
   Entry item = it.next();
   map.remove(item.getKey());
}

This will throw a ConcurrentModificationException when the it.hasNext() is called the second time.

Question is duplicated

yanefedor
  • 2,132
  • 1
  • 21
  • 37