aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes lock method without lock cookie? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "lock method without lock cookie?" Watch "lock method without lock cookie?" New topic
Author

lock method without lock cookie?

Bably Das
Greenhorn

Joined: Sep 17, 2009
Posts: 28
Hello all,
I am using a thin client and my business service layer has two methods search and book. My lock method doesnot have a lock cookie so from what I have read in the forum, I understand that I need to generate a unique value by doing System.nanoTime(). I am not so clear about the lock cookie concept and what role will it have in stand alone mode. If the book method of my business layer is of the signature


then how do I get the cleintId value for the standalone mode. Can anyone please clarify my doubts? I have read threads regarding this topic but still am in confusion hence the post.

As always all help highly appreciated!

Thanks,
Bably Das

SCJP 1.5, SCJD (URLyBird 1.3.2)
Vlad Djordan
Greenhorn

Joined: Jan 15, 2010
Posts: 15
Hi,

I understand that I need to generate a unique value by doing System.nanoTime()


You don't HAVE to use this approach, but for the intents and purposes of the assignment it is good enough. Remember to justify the usage in your choices.txt.

I am not so clear about the lock cookie concept.


The lock cookie is used in order to uniquely identify which clients currently hold a lock on a specific record, so that only that client, which holds the lock on a record can modify/update it. This ensures that no other client can modify/update a record while there is a lock on the record by another client.

In short, if client X holds a lock on record 5, then client Y cannot modify/update/delete record 5, until client X is finished using it. The lock cookie enables you to identify the clients in this case.

what role will it have in stand alone mode....then how do I get the cleintId value for the standalone mode.


I don't believe you need to generate the client id using System.nanoTime() in the standalone mode, you can use the current Thread id instead. I think you would only generate the client id in networked mode. There's a good discussion here.

Cheers,

Vlad
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5266
    
  13

Hi Bably,

The explanation of Vlad is excellent The only thing I can add: if you are unclear about the purpose of lock/unlock method and the lockCookie, just have a look at this entry in the ScjdFaq. I'm pretty sure it will clear your doubts.

Kind regards,
Roel


SCJA, SCJP (1.4 | 5.0 | 6.0), SCJD
http://www.javaroe.be/
Bably Das
Greenhorn

Joined: Sep 17, 2009
Posts: 28
Thanks Roel and Vlad for the replies. I guess I now have some understanding on the locking mechanism and client Id but still have some doubts.

Just like the Andrew Monkhouse book I have an Application Runner class and from there Standalone/ Client mode leads to a Main Window class.
In the Main Window class the book button leads me to a new dialog box where a user can enter a 8 digit customer id.
This is in turn calls the book() function of the GuiController class and subsequently the book() function of the LocalServiceImpl.

My business service layer is an umbrella Service interface which is then extended by Local Service and Remote Service interfaces and are implemented by classes called RemoteServiceImpl and LocalServiceImpl.

I am generating the client Id at the RemoteServiceImpl class as I am using the same classes Main window and the CustomerIDEntry to display the gui both for client and stand alone modes.
Is this a correct approach? I think I am missing something?

Thanks,
Bably Das
Bably Das
Greenhorn

Joined: Sep 17, 2009
Posts: 28
I have been thinking a lot about the above but cant seem to find a way to generate the clientId at any place other than the RemoteServiceImpl and still use the same classes to generate the Jtable and the dialog box for both stand alone and client mode. I have setClientId method in my Data class like suggested by Roel and Roberto. In my lock method I am checking if the clientId is null and if that is true I am setting it to the current thread's id for stand alone mode. Any hints/ suggestions on my design highly appreciated!

Thanks,
Bably Das
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5266
    
  13

Hi Bably,

My approach is similar to yours, so I guess it is

ApplicationRunner to start the application. A ServerWindow instance is created when using "server" as argument, a MainWindow instance is created for both the standalone and network client. The MainWindow instance has a reference to my Controller class. This Controller instance has client-id (for identification) and a reference to my BusinessService (which can be a LocalBusinessServiceImpl or a RemoteBusinessServiceImpl).
When the user confirms my book-dialog the method Controller.book is invoked (which invokes of course BusinessService.book).

In my lock method I am checking if the clientId is null and if that is true I am setting it to the current thread's id for stand alone mode.
I do exactly the same (and of course also in update/delete/unlock methods).

Kind regards,
Roel
Bably Das
Greenhorn

Joined: Sep 17, 2009
Posts: 28
Thanks Roel for your reply and again helping me clarify my doubts but still have some....



Now, I dont understand this, why do I need to check the clientId inside update/ delete methods? I do a check inside the unlock method to see if a locked record in my locked record map Hashmap<recNo, cleintID> is locked by a particular client.

I was thinking that if delete is needed in future releases it should be inside lock(), delete(), unlock() like my update() method is inside the block- lock(), update(), unlock() inside my book() method of Service layer.

My update/ delete/ create/ read/ find methods do the work as needed by the interface without doing anything about client ID or locking mechanism. I think now I am defintely missing something?

Thanks,
Bably Das
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5266
    
  13

Hi Bably,

why do I need to check the clientId inside update/ delete methods?
To ensure that the thread who is updating/deleting the locked record actually holds the record (which is the whole purpose of this lock/unlock methods).

I guess in your application it is possible to do something like:
Only threadA may update/delete record 1 after it acquired the lock. ThreadB has to wait until the lock on record 1 is released by threadA (call to unlock), and must lock record 1 prior to updating it.

Kind regards,
Roel
Bably Das
Greenhorn

Joined: Sep 17, 2009
Posts: 28

Thanks again Roel for the reply but after your reply must admit I had to do some more thinking and even decided to switch to the RMI Factory pattern but then suddenly had a flash of lightning

Earlier I thought once a thread say A locked a record say 1, no other thread could modify it unless the thread A unlocks record 1. My lock method checks the locked records map and waits if lock is requested on a record which is already present in the map. Once the record is unlocked all waiting threads are notified in my unlock method.

To ensure that the thread who is updating/deleting the locked record actually holds the record (which is the whole purpose of this lock/unlock methods)


Now I understand that I need to do the above additional check for delete/ update and unlock methods to ensure almost complete thread safety. Is there something more it?

Thanks Roel once again for all the help you are providing in this great forum!

Warm regards,
Bably Das
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5266
    
  13

Bably Das wrote:Is there something more it?
Of course I don't have any idea about what you implemented and how you did it. But if you make sure your Data class is thread-safe and a record can only be updated/deleted/unlocked by a thread owning the lock on that record (by calling lock-method) your Data class is

Have you already thought about the scenario "a thread/client locks (or tries to lock) more than 1 record"?

Kind regards,
Roel
Vlad Djordan
Greenhorn

Joined: Jan 15, 2010
Posts: 15
Hi,

Have you already thought about the scenario "a thread/client locks (or tries to lock) more than 1 record"?


Personally, my locking currently deadlocks in this scenario, and I know why it deadlocks and I know how to fix it, however, for the time being I've decided to document as to why I haven't 'fixed' it. My lock/unlock have been specified with a cookie value, and I have decided to make the lock/unlock methods available to the client, ie. I'm implementing the thick client approach. (Many threads on this forum discuss whether thin client is better than thick client, or whether thin client is more appropriate for the assignment than a thick client, so I won't go into it here. Needless to say, I will document my decision.)

Now, why am I allowing deadlock?

Two reasons:

1. My lock method is defined with these comments:



The above requirement doesn't mention anything about what should happen if a lock already exists on a record and the lock is assigned to the same client, or whether this particular client holds a lock on any other records, it only mentions the different client.

2. The deadlock can occur in the following situation:



However, this can easily be remedied by ensuring the JavaDoc and the choices.txt clearly define that it is the responsibility of the client to ensure lock/update/unlock is one atomic operation, ie. that the unlock is called on a locked record prior to locking the same record again:


When I designed my approach I thought about this scenario and have documented it and believe that as long as this scenario is explained, no marks should be deducted. In fact, I've found others who have done the same thing here.

I may go back and revise this (currently working on the business/rmi/gui portion), but for now I will leave this as is.

Bably, I believe you should be ok with either approach, as long as you document your process clearly, in both the JavaDoc and the choices.txt.


Cheers,

Vlad
Vlad Djordan
Greenhorn

Joined: Jan 15, 2010
Posts: 15
Hi,

I just wanted to add one more thing.

Bably, if your instructions specify that you must handle the situation where the same client tries to lock the same record twice, or tries to lock another record while holding a lock on a different record, then you must handle this scenario. My instructions don't appear to state this as a 'must' requirement, therefore, I think as long as its documented, it should be fine.

Furthermore, I think another approach at handling the same client trying to get a lock on a record it already has a lock on, is to just return the previously generated cookie value. Since we already know it has locked this record, I think it is safe to return that cookie value again instead of an Exception. I haven't looked through the forum, but I don't see why this would be an invalid approach. An exception could be thrown then only if the same client tries to lock a record while already holding a lock on another record.

For example,

Client A:


Client A:


I think in the above two scenarios Roel's code might throw an Exception, possibly IllegalStateException, in each case, but I think both variations are fine. Also, allowing the deadlock, but explaining it, if your instructions don't clearly say that you must handle the situation, is ok as well.

Cheers,

Vlad
Bably Das
Greenhorn

Joined: Sep 17, 2009
Posts: 28
Thanks Vlad for your replies. My lock method clearly states that
// Locks a record so that it can only be updated or deleted by this client.
// If the specified record is already locked, the current thread gives up
// the CPU and consumes no CPU cycles until the record is unlocked.


So the requirement to check what happens if the same client locks the same record twice or tries to lock another record is not explicitly mentioned. Like you I am also working on the gui/rmi part now and will have to come back to locking again. I guess I will throw an IllegalStateException for these conditions and explain them properly in JavaDoc/choices.txt but still need to think more on these situations.

Thanks again for all your time and help!

Cheers,
Bably Das
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5266
    
  13

Hi Vlad,

How handling these situations depends on the assignment you have: if you have one with a lockCookie you have the advantage that you can identify a client really easy. If you don't have such a cookie, you have to create your own mechanism to identify each client (a bit harder, using a clientId for example) but you have the advantage that it becomes a whole lot easier to determine when a client is locking a record twice or trying to lock another record when already having locked another record. Hence, it is pretty straightforward to avoid a deadlock situation (and you are correct: I throw the IllegalStateException when these situations might occur).

My instructions don't appear to state this as a 'must' requirement, therefore, I think as long as its documented, it should be fine.
I don't think no instructions explicitly mention handling deadlock as a must-requirement. But in my opinion it is inherently a part of this must-requirement Your server must be capable of handling multiple concurrent requests, and as part of this capability, must provide locking functionality as specified in the interface provided above.: if your server deadlocks, it is not capable of handling multiple concurrent requests. So you should always handle a possible deadlock situation: with code (if possible) or in documentation (javadoc) and choices.txt (to clearly prove you are aware of this scenario and you have thought about it).

I think another approach at handling the same client trying to get a lock on a record it already has a lock on, is to just return the previously generated cookie value. Since we already know it has locked this record, I think it is safe to return that cookie value again instead of an Exception.
In my opinion you will only be safe if data.lock(1) is called from the same client! Otherwise 2 different clients will have same lockCookie value and might end up in overwriting each other's updates. And with a lockCookie that is the whole problem: how do you determine that data.lock(1) is called from the same client-application? If you could determine that you would be able to handle deadlock situation within your code.

Kind regards,
Roel
Vlad Djordan
Greenhorn

Joined: Jan 15, 2010
Posts: 15
Hi Roel,

In my opinion you will only be safe if data.lock(1) is called from the same client! Otherwise 2 different clients will have same lockCookie value and might end up in overwriting each other's updates. And with a lockCookie that is the whole problem: how do you determine that data.lock(1) is called from the same client-application? If you could determine that you would be able to handle deadlock situation within your code.


First of all, I was referring to a situation where there is a clear mapping between clients (not cookies) and record numbers, and Bably suggests such a structure exists in one of his previous posts. Therefore, I will explain this again. I will use your examples of IllegalStateException:

Scenario 1:
Client A tries to lock record 5.
Client A locks record 5.
Client A tries to lock record 5 again. ---> IllegalStateException is thrown

Scenario 2:
Client A tries to lock record 5.
Client A locks record 5.
Client A tries to lock record 6. ----> IllegalStateException is thrown

You are able to do this because you map client id's to record numbers, or you have a structure which keeps track of which client has a lock on which record. Now then:

Scenario 1:
Client A tries to lock record 5.
Client A locks record 5.
Client A tries to lock record 5 again. ----> No need for the Exception! Why? Because you already keep a track of which client has a lock on record 5 and that is client A. If client B tried to lock record 5, you would not return at this point and would make Client B wait until client A is finished with the record.

I was only trying to explain to Bably that an IllegalStateException can be thrown in this scenario, but it can be handled by another approach.


Your server must be capable of handling multiple concurrent requests, and as part of this capability, must provide locking functionality as specified in the interface provided above.


Of course it does. I would not have been able to run successful tests if it didn't. There is no deadlock in my code regarding different clients accessing sensitive data, but that wasn't your question. Your question was:

Have you already thought about the scenario "a thread/client locks (or tries to lock) more than 1 record"?


In your code you handle this with IllegalStateExceptions, and while currently my code may deadlock (in this situation only) I have clearly documented why that is. I even mentioned that I may change this portion later and that I make lock/unlock available to the client, ie. I'm implementing a thick client.

My only point to Bably was that since there is a structure that maps clients to record numbers he can:
1. Throw IllegalStateException in both cases, as you.
2. Throw IllegalStateException in only one case, and in the other 'allow' it.
3. Document only that this is a possibility for deadlock, but the only deadlock possibility, ie. his locking ensures Client A and Client B aren't deadlocked for some other reason.


Cheers,

Vlad
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5266
    
  13

Vlad Djordan wrote:First of all, I was referring to a situation where there is a clear mapping between clients (not cookies) and record numbers
...
I was only trying to explain to Bably that an IllegalStateException can be thrown in this scenario, but it can be handled by another approach.
If you were referring to that specific situation, my remark was not needed (and completely useless). But because that was not clear to me (and maybe some other ranchers in the near future) I made my remark.
Anyhow your explanation is excellent and will certainly be referenced from other threads regarding this issue.

Kind regards,
Roel
Vlad Djordan
Greenhorn

Joined: Jan 15, 2010
Posts: 15
Hi Roel,

If you were referring to that specific situation, my remark was not needed (and completely useless). But because that was not clear to me (and maybe some other ranchers in the near future) I made my remark.


Your remark certainly wasn't 'useless' and I will try and do a better job of being clearer in the future, both when asking questions and providing feedback.

Cheers,

Vlad
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
 
subject: lock method without lock cookie?