my dog learned polymorphism*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Wait in lock method Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "Wait in lock method" Watch "Wait in lock method" New topic
Author

Wait in lock method

K. Tsang
Bartender

Joined: Sep 13, 2007
Posts: 2247
    
    7

Hello I have a minor question about locking. We need to use the wait() method in our lock method somewhere. Suppose I use a collection (lockedSet) to store locked records and check if this collection is empty before adding the record, else it waits. Ignoring exceptions:



Now if it goes into wait, will it still add the record after wait (line 2) or I need to add in line 6 manually?

I asked this because when I run isLocked method it returns false!!!

My testing code for update:


K. Tsang JavaRanch SCJP5 SCJD/OCM-JD OCPJP7 OCPWCD5
Julio Cesar Marques
Ranch Hand

Joined: Mar 21, 2009
Posts: 66
Hi Buddy!

Methods isLocked, lock, unlock have to be mark as synchronized and use notify or notifyAll to release locks locked by wait()!

;)


Julio Cesar Lopes Marques
Sun Certified Java Developer 5, Sun Certified Java Programmer 5
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11404
    
  81

I don't really understand your code. Your comment states that you "check if this collection is empty before adding the record", however your code does exactly the opposite: "if (! lockedSet.isEmpty())"

I also don't understand why your collection needs to be empty before you can add a record. Isn't it desirable that someone can lock record 7 at the same time someone else locks record 9? In which case, wouldn't both those numbers be added to the collection?

You really must put your check for whether the the individual record is currently locked inside a loop of some kind. Ignoring the problem above, with your current code we have the potential situation that:

Since notifyAll() was called, both thread B and thread C received the notification, and now both thread B and thread C think that they have the record locked!

Change the logic to a loop and you avoid this potential problem.

Note: I have not given a solution here because I believe it is one of the most fundamental issues you must understand in the project, and just giving away a solution will not help readers understand the issue. If you have any questions at all, please ask!

Regards, Andrew


The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
K. Tsang
Bartender

Joined: Sep 13, 2007
Posts: 2247
    
    7

Sorry about the type it should have been


The idea is really only allow one write thread to do update/delete. So I thought of making sure the lockSet is empty before the record can be added and becomes locked.

Now my original testing was if the lockSet IS NOT empty, it waits. But after the wait completes, does the code finish without adding the record or will it also add the record automatically?

From my testing code, when I printed out isLocked, it can be false which seems not right - how can lockSet need have record and allow update/delete? So that's why do I need to manually add in the "lockSet.add(recNo)" line after wait?

Also from Andrew's given scenario: Threads B and C should not able to both lock record 5 at the same time. Because if B and C do successfully lock record 5, B updates customer ID "11111" and C updates customer ID "44444" then on the data level it's inconsistent. Of course in my app it does check if the customer ID is already filled in before updating.

Hope this is better for you guys to understand.

My sample test run output only for update:
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11404
    
  81

K. Tsang wrote:do I need to manually add in the "lockSet.add(recNo)" line after wait?


Yes you do. When you call "wait()" the tread blocks at that particular line in the code. When you later call "notify" or "notifyAll" the execution of that code resumes at the point where it had been blocked. So it will resume at line 6 - it does not have any way of knowing any other line number you might prefer to go back to.

K. Tsang wrote:Also from Andrew's given scenario: Threads B and C should not able to both lock record 5 at the same time.


We are both in agreement about that, however my issue is that I believe your code will allow both threads B and C to lock record 5 simultaneously.

My code is a little odd, simply because I am cheating with the unlocking of the record, but it should look familiar to you:

Now look at the output:

With no particular reason, thread C happened to get the lock first at 13:41:26. Threads A & B also attempted to get the lock mere milliseconds behind thread C, but they were too late. So they got blocked for 5 seconds while thread C does it's work.

Thread C finished it's work at 13:41:31 and called notifyAll. This resulted in Thread A waking up and getting the lock, and within milliseconds thread B woke up and also got the lock.

Threads B and C then continued to work simultaneously, both believing that they own the one true lock. They both finished simultaneously at 13:41:36.

Feel free to modify my "Tsang" class to call your lock and unlock methods as appropriate, and test with your system. I believe you will find that multiple threads can own the same lock simultaneously.

Regards, Andrew
K. Tsang
Bartender

Joined: Sep 13, 2007
Posts: 2247
    
    7

Thanks Andrew. I finally got the waiting business working. Now I really did achieve single thread write operation. Now I need to double check my create method to do the same concept.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Wait in lock method
 
Similar Threads
B&S: locking etc
NX: Assignment - some design questions
pls validate my locking strategy - all inputs are g8ly appreciated. (URLyBird)
Record locking on recNo
Tests for the Data class/locking mechanism