Problem with wait(), notify() and IllegalMonitorStateException
Joined: Feb 23, 2009
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.
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.
Jeez right. You have to own the lock when using wait or notify. Thanks :-)
Joined: Apr 04, 2005
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 ??
Joined: Feb 23, 2009
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.
Joined: Apr 04, 2005
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