Yet another thread about the locking mechanism. I've been reading through countless of threads but I'm still confused about a couple of things.
In my implementation I cache the contents of the database file to a HashMap.
I am now trying to implement my locking mechanism but I'm still not sure about a couple of things:
In several threads I read that people are locking and unlocking in de delete()- and book()-methods. For the delete()-method this seems fine but I can only see this working for the book()-method if the client specifies the userID for the booking right away. I had the following in mind (while also taking in account that the same flow could be used for an update action):
1) The user has the view with the table with all records in front of him, he decides he want to book record number 20 and selects the record and presses the book-button.
2) A detailview is opened, using the selected recordID the correct record is fetched from my cache using the read()-method and the record's field values are filled in. All of them are not editable except for the 'userID'-field.
3) User enters a name in the 'userID' field and clicks on the Save-button.
4) The record is updated.
How would this work if the locking mechanism is executed in the book()-method (in my case the method executed when the user clicks on the Save-button in my detailview)? Also by doing so multiple users would still be able to select this record and click on the Book-button in the table view, getting the detailview.
As far as I can see this may not happen and as soon as the user opens the detailview the record must be locked (step 1) so other users cannot open it. The record will then remain locked until finally step 4 has been reached. However by doing so other questions arise, like let's say the first user wants to book record 20, the detailview opens and the user goes away for 2 minutes, rendering the record locked. Another user wants to book record 20, the record is locked so the user's thread get put to sleep until it becomes available. Does this mean that the user's GUI will hang until the first user either cancels the detailview or clicks save (judging by the javadoc of the lock()-method: "If the specified record is already locked, the current thread gives up the CPU and consumes no CPU cycles until the record is unlocked")?
I wouldn't let the Thread of the second user wait until the record becomes available, instead I would present a message that the record is in use at the moment so that user 2 can go on with his business instead of hanging until user 1 is done.
The scenario to book a record is spot on! That's exactly how i implemented it. My booking logic has a few additional steps than lock/update/unlock to prevent double bookings.
Why would you think it would not work?
Joined: Dec 15, 2010
Thanks for the input, Roel. I was worried I might overlooked something simple.
You can take a look at Roberto Perillo's Test class for reference.
The key implementation is:
When one user clicks your save button, the record_Number (eg record 20 ) is locked, updated and unlocked.
When a second user attempts to lock record 20, this user needs to wait until the record 20 has been successfully unlocked.
So, in your lock method, provide a wait method and in your unlock method , provide your notifyAll method.
Joined: Jul 29, 2012
Does this mean that the user's GUI will hang until the first user either cancels the detailview or clicks save (judging by the javadoc of the lock()-method: "If the specified record is already locked, the current thread gives up the CPU and consumes no CPU cycles until the record is unlocked")?
This idea is good, but you can try something simple. "Simplicity is the key" in terms of the exam.
The second user's GUI may not need to hang. If the first user has already booked the record 20, the second user will get a "RecordAlreadyBooked" exception from the screen.
If the first user is booking the record, the second user will wait. That will satisfied "the current thread gives up the CPU and consumes no CPU cycle until the record is unlocked."
Create two threads that shares the same object, sharedRecord.
Use code similar to this for your synchronized lock method
Use this for your synchronized unlock method
This is the key thing your exam grader is looking for. If you miss this or if you get a deadlock, you will fail the whole exam according to Roberto.