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