• 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
  • paul wheaton
  • Jeanne Boyarsky
  • Ron McLeod
Sheriffs:
  • Paul Clapham
  • Liutauras Vilda
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Roland Mueller
Bartenders:

Locking & Threading Issues...HELP!

 
Ranch Hand
Posts: 181
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This question is a spinoff from a previous post. I am doing extensive testing on my locking and I want to ask a few questions. First of all, in local mode (haven't done networking yet), I have a Facade pattern that exposes the business methods book and search to the client. Here is a snippet of my book method:

Is it wrong to call unlock in the finally method? I'm a bit rusty on try/catch/finally. Will finally always be called? Before, I called unlock inside the try block, however, if a user tried to book a record that has already been booked, a BookException would be thrown and my unlock method would never be called. Thus, I decided that I could call unlock in finally because whether or not an exception is thrown, unlock will be called. How did you guys solve this issue?

Here is my second question in my lock class. After some great posts by Peter, he brought to my attention two concepts: preventing a thread from attempting to lock multiple records concurrently and preventing a thread from trying to lock a record it already has locked. I solved this issue by creating a HashMap that held key-values of record number-Thread name. However, here's a problem I found after implementing it. I created a little run method with the following:

I printed out some lines during different points in the execution. Here is the console:

Thread-3 Enters Locking.

Thread-3 Trying to lock record number: 0

Thread-3 Places Cookie: 0 in Hashmap

Thread-3 Enters Locking.

The current thread either has this record locked or it is attempting to lock multiple records concurrently.


Thread-3 enters lock, locks the record and places record into hash. Here is where the problem occurs. I use the same thread to try and lock the same record. The ThreadLockException is thrown. Now, however, when I try to call unlock, it will not run. So my second question is, how do I keep the thread running and allow it to call unlock, even if a duplicate call to lock was made beforehand? For help, here is what a correct output would look like:


AWT-EventQueue-0 Enters Locking.

AWT-EventQueue-0 Trying to lock record number: 16

AWT-EventQueue-0 Places Cookie: 16 in Hashmap

AWT-EventQueue-0 Enters Unlocking.

AWT-EventQueue-0 Removes Cookie: 16 from hashmap.

AWT-EventQueue-0 Removes Itself from Thread Manager.

All threads notified.


Any help would be so much appreciated. Thank you for all of your help lately!
[ January 11, 2005: Message edited by: Daniel Simpson ]
 
Ranch Hand
Posts: 85
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If you are rusty on try-finally, maybe you should have a look at your SCJP books
The finally clause always gets called.
Is there a point in calling the unlock method if a lock method did not return successfully?
Also note that any exception thrown in your try clause can be 'overruled' by an exception thrown in your finally clause.

Good luck!
Dies
 
Daniel Simpson
Ranch Hand
Posts: 181
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Dieskun Koper:
Is there a point in calling the unlock method if a lock method did not return successfully?

Well here is what's happening. Before, I had my unlock in the try clause. It did this sequence lock-read-verify-update-unlock. However, if the verification proved to be that the record was already booked, the book exception was thrown, exiting the try statement (skipping the unlock) and leaving that record forever locked. I decided to put the unlock in finally because of that to make sure unlock would always be called. (Keep in mind, that if it calls lock and the record is booked, it will halt and wait for it.) Is there a better way in doing this? Also, I COULD change the sequence to read-lock-read-update-unlock, but that seems a bit repetitive, I think. Keep in mind that I just started the networking portion, so all the above is being tested in local (I'm using locking in local). Say a thread calls something like:


The thread would aquire the lock on record 0, then try to re-lock it, causing it to wait forever. I avoid this by keeping a HashMap of thread names who are holding locks and make sure that the current executing thread doesn't already hold a lock. If it does, it throws a ThreadLockException (maybe that's a bad name for it).
 
Dieskun Koper
Ranch Hand
Posts: 85
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
How about the following:

long c = data.lock(recNo);
try {
// validate owner field and see if it is available to book, etc.
}
catch {...
}
finally {
data.unlock
}

Here, if your lock method throws an exception (i.e. definitely did not get a lock), it won't try to unlock it (which might cause another exception).
 
Daniel Simpson
Ranch Hand
Posts: 181
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Dieskun Koper:
How about the following:

long c = data.lock(recNo);
try {
// validate owner field and see if it is available to book, etc.
}
catch {...
}
finally {
data.unlock
}

Here, if your lock method throws an exception (i.e. definitely did not get a lock), it won't try to unlock it (which might cause another exception).


Good idea, Dies, except one problem. My lock method throws 1)the checked exception RecordNotFoundException and a runtime ThreadLockException (name pending). So it needs to go in some sort of try statement. If it didn't throw exceptions, your idea would be excellent. What do you think? Or am I misunderstanding what you are suggesting?
 
Dieskun Koper
Ranch Hand
Posts: 85
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I don't know when your ThreadLockException gets thrown, but if the record does not get locked when it's thrown but you want to catch and wrap this exception, just add another try-catch around the try-catch-finally. If the record gets locked before this exception is thrown and it needs to be unlocked, you are stuck with an ugly design and only surgery can fix that.
 
Daniel Simpson
Ranch Hand
Posts: 181
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Dieskun Koper:
I don't know when your ThreadLockException gets thrown, but if the record does not get locked when it's thrown but you want to catch and wrap this exception, just add another try-catch around the try-catch-finally. If the record gets locked before this exception is thrown and it needs to be unlocked, you are stuck with an ugly design and only surgery can fix that.


Here is a part of my locking solution:



So if a thread already has a record locked, whether the same one or a different one, that ThreadLockException will be thrown before it can even lock it. I'm sure this makes my design quite alright.
 
Daniel Simpson
Ranch Hand
Posts: 181
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
P.S.- If anyone can think of a better name for my exception ThreadLockException, let me know. I don't think that name describes the exception very well and at first glance you would think it has to do with threads deadlocking. However, I am doing logical locking with the threads to make sure it can't (as my Javadoc for that exception describes):

ThreadLockException is thrown if a thread attempts to 1) lock a record
* that itself has already locked or 2)lock multiple records in the database
* while it is already holding a lock on a record.


Thanks!
 
Ranch Hand
Posts: 1033
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Daniel Simpson:
P.S.- If anyone can think of a better name for my exception ThreadLockException, let me know. I don't think that name describes the exception very well and at first glance you would think it has to do with threads deadlocking. However, I am doing logical locking with the threads to make sure it can't (as my Javadoc for that exception describes):

Thanks!



Given that I use RMI and need to make this work without reference to threads and it relates to is deadlock detection, I use DeadlockException("deadlock possible"). If I detected a real deadlock I'd use DeadlockException("deadlock detected"). You could also use java.lang.IllegalArgumentException, since relocking or multiple locking is an illegal argument to lock.
 
I don't get it. A whale wearing overalls? How does that even work? It's like a tiny ad wearing overalls.
Smokeless wood heat with a rocket mass heater
https://woodheat.net
reply
    Bookmark Topic Watch Topic
  • New Topic