• Post Reply Bookmark Topic Watch Topic
  • New Topic

Current thread not owner  RSS feed

 
Steve Granton
Ranch Hand
Posts: 200
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
I'm writing a Lock Manager class to control the locking and unlocking of records. The code for the lock manager is seen below:

When I exercise the lock method with:

I get the following error:
Testcase: testLockRecord took 0.06 sec
Caused an ERROR
current thread not owner
java.lang.IllegalMonitorStateException: current thread not owner
at java.lang.Object.notifyAll(Native Method)
at suncertify.db.DatabaseLockManager.lock(Unknown Source)
at suncertify.junit.DatabaseLockManagerTest.testLockRecord(Unknown Source)
at java.lang.reflect.Method.invoke(Native Method)
at junit.framework.TestCase.runTest(TestCase.java:156)
at junit.framework.TestCase.runBare(TestCase.java:130)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:121)
at junit.framework.TestSuite.runTest(TestSuite.java:157)
at junit.framework.TestSuite.run(TestSuite.java:152)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:231)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:409)
Can anyone explain why the current thread is not the owner and cannot call notifyAll()? I'm confused since the current thread has the monitor of the object.
Cheers,
Steve
 
Max Habibi
town drunk
( and author)
Sheriff
Posts: 4118
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Steve,
I know exactly what's wrong.
You need to wait(and notifyAll) on lockedRecordMap, not the the this object. That is, where you currently say

you need to say

Here's the problem. When you say myObject.wait() , what you're saying to the JVM is "mr. JVM, please stop executing the current Thread until myObject is unlocked".
But that's not what your (current) code block is saying: Since you're just calling wait() , you are, in fact, calling this.wait() . That is, you're calling wait on the this object.
You're saying to the JVM
"mr. JVM, please stop executing the current Thread until this is unlocked".
And the JVM is responding back to you by saying
"mr. Programmer, you don't own the this object, so how dare you tell me what to do with it?".
And the JVM is right: you don't own the this object. Why not? Because you didn't synchronize on this , you synchronized on lockedRecordMap .
You could have done so by synchronizing the method or syychronizing explicitly on this , but I don't think you want to in this case.
I actually delve into this topic pretty deeply in my forthcoming book, found here
HTH,
M
[ July 15, 2002: Message edited by: Max Habibi ]
 
Steve Granton
Ranch Hand
Posts: 200
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Max,
Thanks, that worked a treat.
Cheers,
Steve
 
Max Habibi
town drunk
( and author)
Sheriff
Posts: 4118
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Glad to be of service. It sounds like you're preping for SCJD exam. Which jdk are you using?
M
 
Steve Granton
Ranch Hand
Posts: 200
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Max,
I'm currently using the 1.3.1_03-b03. Though I don't imagine that there is much difference between any of the 1.3.1 versions.
Are Sun going to mandate that the 1.4 JDK is used?
I'd welcome any advice you have on my locking mechanism. The unlocking is quite similar though I do have one slight dilema.
Since I'm using RMI the locking strategy is based on the fact that only the thread that locked the record can unlock it. This would be fine if the RMIRegistry does not use a thread pool to service requests. Obviously, a thread pool would mean that a different client could be assigned the same thread and could therefore unlock a record that it didn't lock. The worst case would be if the Registry server was not multithreaded and only used ONE thread for all clients (I know this is unlikely but it is an implementation detail), since this would mean that every client could unlock any record they choose.
There is also the side issue of a reference to the thread remaining in the HashMap until a client unlocks the record. This could result in a memory leak as a dead thread could not be garbage collected.
I've got a funny feeling I'll need to re-think this locking strategy.
Do you have any thoughts on this?
Cheers,
Steve
 
Max Habibi
town drunk
( and author)
Sheriff
Posts: 4118
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Steve,
Using 1.4 is not mandated for the SCJD: however, I can't really see any reason not to use it: with regex support, exception chaining, interuptable File IO, Channels, etc., there are a lot of good tools available there that were not available before.
My opinion is that it will make passing the test easier, because it offers you more abilities.
This is sort of the point of my book, in addition to exploring the details of how(and why) RMI, Swing, and Threading work. I didn't just want to write a book to write a book: My goal was to provide a useful resource.

As for your locking issue:
Since I'm using RMI the locking strategy is based on the fact that only the thread that locked the record can unlock it.

My advice is to be somewhat careful here. Read the documentation for your unlock method very carefully. From what you're saying, I'm not sure that you're adhearing to the letter of the unlock method, as it was presented to me.

This would be fine if the RMIRegistry does not use a thread pool to service requests. Obviously, a thread pool would mean that a different client could be assigned the same thread and could therefore unlock a record that it didn't lock. The worst case would be if the Registry server was not multithreaded and only used ONE thread for all clients (I know this is unlikely but it is an implementation detail), since this would mean that every client could unlock any record they choose.

Well, there are lot of potential directions to explore here. I don't want to give away too much(and I wouldn't want to deter you from buying my book ), but there are other solutions, even using RMI. For example, you know that each RMI object get's at least one thread per client: so what if each GUI client got thier own RMI object, and all of those RMI object coordinated though a single threadsafe object? Maybe a factory(say, an RMI object itself) could create these RMI objects for you? Does this sound like the way ejbs work with the Home interface? Just some food for thought...

There is also the side issue of a reference to the thread remaining in the HashMap until a client unlocks the record. This could result in a memory leak as a dead thread could not be garbage collected.

Try exploring the object
here
HTH,
M
[ July 15, 2002: Message edited by: Max Habibi ]
 
Steve Granton
Ranch Hand
Posts: 200
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Max,
Thanks for the help and the ideas. As I thought, time to rethink my locking strategy!!! :-)
Maybe the moderator of this forum can move this to the Developers Certification forum so others can benefit.
Cheers,
Steve
 
Max Habibi
town drunk
( and author)
Sheriff
Posts: 4118
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Steve Granton:
[QB]Max,
Thanks for the help and the ideas. As I thought, time to rethink my locking strategy!!! :-)

Happy to be of any service. IMO, one of the major points of the developer exam is the fact that's a fun, if complex, assignment. Of course, thre are some very practical reason to take it, but I really enjoyed the process of solving the problems themselves, and I learned quite a bit in doing so. So I would suggest that you enjoy that part

Maybe the moderator of this forum can move this to the Developers Certification forum so others can benefit.

I'm ok with that. I'm even willing to set up a discussion forum.
Best regards,
M
[ July 16, 2002: Message edited by: Max Habibi ]
 
Lucy Sommerman
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
//using hash map -

get current thread now owner..with the following code - seen a few notes on this..nothing definitive..HashMap being unsynchronised should be ok - this is within a synchronised block.?

while ((!locks.isEmpty()) && (locks.containsKey("-1") || locks.containsKey(new Long (recordId)))) {
try {
locks.wait(5000);
}
 
Ernest Friedman-Hill
author and iconoclast
Sheriff
Posts: 24217
38
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
To call wait() or notify() on an object, the calling thread has to hold the monitor on that object. To be holding the monitor, the calling thread has to be in a synchronized method of that object, or in a synchronized block which is synchronized on that object. Being synchronized on some other object doesn't help.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!