IllegalMonitorStateException - Lock lost, but why?
I have some kind of synchronization problem. somehow I get an IllegalMonitorStateException when calling notify on an object, but this object is within a synchronized block! The code looks like this:
privatevolatile Set<K> set =new HashSet<K>();
private Map<K, ArrayList><Listener>> map =new HashMap<K, ArrayList><Listener>>();
publicvoid findClass(K key, Listener listener){
synchronized (set){
synchronized (map){
set.add(key);
ArrayList<Listener> listeningClasses = map.get(key);
if (listeningClasses ==null){
listeningClasses =new ArrayList<Listener>(2);
map.put(key, listeningClasses);
}
listeningClasses.add(listener);
}
set.notify();
}
}
publicvoid run(){
while (!stopped){
synchronized (set){
while (set.size() == 0){
try{
set.wait();
}catch (InterruptedException e){
}
}
}
// create a new map and exchange it with the publicly accessible map
Set<K> curSet =null;
Set<K> newSet =new HashSet<K>();
synchronized (set){
curSet = set;
set = newSet;
}
}
As far as I know about synchronization this should work. A single thread waits within its run method. This wait is within the synchronized block. When findClass is called, an entry is added to the set and finally notify is called to wake up the thread.
The line that calls notify triggers the IllegalMonitorStateException. As the object referenced by set doesn't change, as changing of the referenced object also happens within a synchronized block.
The exception only occurs quite rare, but is a big problem for the application I am working on. Has anyone an idea?
Greetz, max

