aspose file tools*
The moose likes Threads and Synchronization and the fly likes Problem with wait(), notify() and IllegalMonitorStateException Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Problem with wait(), notify() and IllegalMonitorStateException" Watch "Problem with wait(), notify() and IllegalMonitorStateException" New topic
Author

Problem with wait(), notify() and IllegalMonitorStateException

Sebastian Janisch
Ranch Hand

Joined: Feb 23, 2009
Posts: 1183
Hey,

my threading seems to be a little rusty. I am creating a TestCase for JDBCSupport and trying to provoke an exception that is thrown when different threads use Connection objects and try to use those once they are released back into the pool.

The problem is when I invoke wait I am getting an IllegalMonitorStateException and I have no clue why.

Here is the code. The comment says the expected flow.


Thanks for help

JDBCSupport - An easy to use, light-weight JDBC framework -
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19760
    
  20

Those methods can only be called if you are synchronizing on the object you are calling the method on:
Be careful that if you synchronize on two objects at the same time you synchronize in the same order. If you somewhere else write you risk deadlock; the outer synchronized block creates two locks, then the inner blocks block because the outer blocks still have the locks. By always putting these nested blocks in the same order you avoid that risk.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Sebastian Janisch
Ranch Hand

Joined: Feb 23, 2009
Posts: 1183
Jeez right. You have to own the lock when using wait or notify. Thanks :-)
Alan Mehio
Ranch Hand

Joined: Apr 04, 2005
Posts: 73
Sebastian,
Just looking at your code I am still not getting to undrstand how the two thread will wait? the threads has to acquire a lock on an object in your case do you want
the connection pooling to be the one.

First of all your thread get created in a method any idea why? second you mentioned



# /*
# * This is what happens:
# * Thread 1 obtains a connection and closes it again (connection gets released into the pool)
# * Thread 1 then notifies Thread 2 which was waiting.
# * Thread 2 obtains a connection and runs a query (no exception expected).
# * Thread 2 then notifies Thread 1 which was waiting.
# * Thread 1 uses the connection instance it previously closed which should now be locked (Exception expected).
# */


Thread 2 notifies thread1 on what waiting object?

If Thread1 uses the connection instance it previously closed ( returned to the pool). So how do you know that this is the connection which was used when you ask the pool for another connection from thread1


The idea is not clear for me. CAN YOU PLEASE ExPLAIN what do you want to prevent such as:
" I want a connection pool which will block any thread asking for connection if there is another thread working with the connection and once the another thread
get the connection back to the pool the thread get notified and start to use the connection again." So you want to prevent the same connection to be used
at the same time from many thread; you want the connection to be used by one thread at a time and allowing other threads to obtain the this connection but not to use it i.e wait ( block) until the first thread finishes from it.

Do you mean it is a kind of blocking queue where other thread has to wait for the resource until the resource will be available i.e returned back to the pool ??




Regards,
Alan Mehio
London, UK
Sebastian Janisch
Ranch Hand

Joined: Feb 23, 2009
Posts: 1183
Hey,

the problem has been solved already by simply surrounding the wait and notify calls with a synchronized block. I'll explain anyway.

JDBCSupport is a database interaction framework which I came up with.

It has a build in connection management which takes care of opening, closing and pooling connections.

When a thread calls getConnection for the first time, the framework establishes a Connection to the server and hands it out to the calling thread.
If the calling thread then releases it back into the pool, the framework won't close the connection but put it into an idle pool until the next client wants to obtain a connection.

The problem is that even though a thread released the connection back into the pool by calling it's close method, it could still call methods on it because it still has a reference to it. That is why all methods on the connection instance get locked as soon as it is released into the pool. So if after releasing, the thread calls a method, it will get an IllegalAccessException.

So far so good. Now what happens if thread 1 releases the connection back into the pool, thread 2 comes by and obtains a connection (it gets served the connection that has been released into the pool previously) and wants to work with it. The framework unlocks the connection instance and serves it.
Thread 1 still has a reference to it and is now able to again call methods on that instance even though it is not allowed to. That is why I decided to mark each connection instance with the id of the thread that is allowed to work with it.

The test case tries to provoke a scenario in which a thread 1 has a reference to a connection, then releases it into the pool and thread 2 obtains it.
The test was supposed to validate if the exception really gets thrown.
Alan Mehio
Ranch Hand

Joined: Apr 04, 2005
Posts: 73
Sebastian,
Thanks for getting back and explaining the JDBCSupport tool.

That is why I decided to mark each connection instance with the id of the thread that is allowed to work with it.


Yes this is a good idea.

I got confused since your sample code does show thread created in a method which make the object thread safe




Cheers
Alan
Sebastian Janisch
Ranch Hand

Joined: Feb 23, 2009
Posts: 1183
I'm happy that you like it :-)
 
jQuery in Action, 2nd edition
 
subject: Problem with wait(), notify() and IllegalMonitorStateException