• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

IllegalMonitorStateException

 
David Reck
Ranch Hand
Posts: 37
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is the basic structure of my lock and unlock method:
public void lock(int record) throws IOException, DabaseException {
synchronized(r_lock) {
while(r_lock has the lock I need) {
try {
wait();
}
catch(InterruptedException e) {
throw new IOException("Unable to lock record.");
}
}
r_lock.add(new Integer(currentRecord));
}
}
public void unlock(int record) {
synchronized(r_lock) {
//verfiy the record for unlocking is actually locked
if(r_lock.contains(new Integer(record))) {
r_lock.remove(new Integer(record));
}
r_lock.notifyAll();
}
}
r_lock is a Vector. My application books seats in a flight database. When I have multiple clients running and they all try to make reservation on the same flights with the total of the clients exceeding the number of seats I get an IllegalMonitorStateException. Should I just catch IllegalMonitorStateException in my booking exception and consider it a request that failed because there were not enough seats availabe? I have also tried r_lock.wait() instead of just wait(), but that gives me messages saying all booking requests completed successfully even when there were do few seats in the database. What am I doing wrong?
 
Sajid Raza
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
<pre>
public void lock(int record) throws IOException, DabaseException
{
synchronized(r_lock) {
while(r_lock has the lock I need) {
try {
wait();
} catch(InterruptedException e) {
throw new IOException("Unable to lock record.");
}
}
r_lock.add(new Integer(currentRecord));
}
</pre>
This first method should fail. You are obtaining a lock on 'r_lock', but you are calling 'wait' on 'this' object that contains the lock method. You cannot call 'wait' on an object whose lock you do not own. Which is what seems to be the case with the first method.

<pre>
public void unlock(int record)
{
synchronized(r_lock) {
//verfiy the record for unlocking is actually locked
if(r_lock.contains(new Integer(record))) {
r_lock.remove(new Integer(record));
}

r_lock.notifyAll();
}
}
</pre>
The problem with the secod method 'unlock' is that you're not really notifying any threads since the 'lock' implementation is incorrect. I would strongly suggest that you do not catch an <code>IllegalMonitorStateException</code> anywhere in your code. I think what you may want to do is pick up a standard operating systems theory text-book and read about mutual exclusion and concurrency. My university's OS course really helped clarify things for me, at least I hope it did.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic