Synchronization Problem

S

Sami Lakka

Hello,

I have created an simple cache class, that allows items to be
added to HashMap. Every public method that uses that map,
is protected with synchronized keyword. The class also contains
an handleNotification method that is called periodically. This method
iterates over the map and refreshes the values in the map. The problem
is that when I test this class with Junit test i get
java.util.ConcurrentModificationException.
I don't understand why, because the handleNotification method is also
synchronized.
I managed to solve the problem using Doug Lea's java.util.concurrent
package, but
I would like to know why my test fails.

Best regards,

- Sami Lakka


Heres the code :
public synchronized void handleNotification() {

try {

Set keys = cache.keySet();

Iterator iter = keys.iterator();


while (iter.hasNext()) {

String tagName = (String) iter.next();

IItem item = backEnd.read(tagName);

cache.put(item.getTagName(), item); // Adds the item to the cache

}


} catch (ItemNotFoundException e) {

e.printStackTrace();

}



public void testHandleNotification() {

MockBackEnd backEnd = new MockBackEnd(3);

Cache cache = new Cache(backEnd);


IItem itemA = new Item("A");

IItem itemB = new Item("B");

IItem itemC = new Item("C");


cache.addItem(itemA);

cache.addItem(itemB);

cache.addItem(itemC);


// (1)

cache.handleNotification(); // ERROR in here.

backEnd.verify(); // Causes the mock to verify that method calls were made



// (2)

int size = cache.getSize();


Assert.assertTrue("Size is incorrect.", size == 3);

Assert.assertTrue("Item's value wasn't modified correctly by the backend",

cache.getItem("A").getValue().equals("MockValue : A"));

Assert.assertTrue("Item's value wasn't modified correctly by the backend",

cache.getItem("B").getValue().equals("MockValue : B"));

Assert.assertTrue("Item's value wasn't modified correctly by the backend",

cache.getItem("C").getValue().equals("MockValue : C"));

}
 
A

ak

this is NOT the synchronisation problem.

Javadoc says "This exception may be thrown by methods that have detected
concurrent modification of a backing object when such modification is not
permissible.
For example, it is not permssible for one thread to modify a Collection
while another thread is iterating over it"

synchronized is just the single put call. your problem is that you change
table while you iterate (multiple calls).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top