• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Ron McLeod
  • paul wheaton
  • Jeanne Boyarsky
Sheriffs:
  • Paul Clapham
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Roland Mueller
  • Himai Minh
Bartenders:

Problem with wait(), notify() and IllegalMonitorStateException

 
Ranch Hand
Posts: 1183
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Sheriff
Posts: 22855
132
Eclipse IDE Spring Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Sebastian Janisch
Ranch Hand
Posts: 1183
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Jeez right. You have to own the lock when using wait or notify. Thanks :-)
 
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 ??



 
Sebastian Janisch
Ranch Hand
Posts: 1183
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 73
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 1183
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm happy that you like it :-)
 
reply
    Bookmark Topic Watch Topic
  • New Topic