I'm working with this scenario: RemoteData implements Unreferenced ClientA requests and receives a reference to RemoteData ClientA requests a lock on record 1 Record 1 is locked ClientA crashes ClientB requests and receives a reference to RemoteData ClientB requests a lock on record 1 ClientB waits... The question here is if the HashMap that stores the [ClientID|Record Number] is in a 'wait' state (because ClientA still has a "ghost reference" to record 1), all the while checking if HashMap.containsValue(recordNum), will the Garbage Collector still kick-in and clean up the dead reference to ClientA? If not, when will unreferenced() be called? There's no way the lock on record 1 can be resolved until unreferenced() is called which has code to release the lock. This is certainly an important issue because a ClientB's request could essentially "hang" for an indeterminate about of time. Has anyone figured this out? [ June 03, 2003: Message edited by: Christian Garcia ]
Yes, I tested with unreferenced and it gets called after about fifteen minutes or so. I think someone has posted a way to adjust this timeout period, but I don't recall how it's done. When you say, "all the while checking if HashMap.containsValue(recordNum)" I assume you mean that after this check, your thread uses wait() to allow the cpu do other things until another thread calls notifyAll(), right? In my implementation, any time any thread unlocks a record, it notifies all waiting threads so they can check and see if their locked record is now available. If it's still locked, they wait again. I probably won't fool with adjusting the timeout period of when unreferenced gets called. I'll just document and say, if a client crashes while holding a lock, the record should become available again after twenty minutes. How often will it happen that two clients want to lock the same record at nearly the same time and one of them crashes?
Joined: Jan 29, 2002
Perry, Regarding your points:
When you say, "all the while checking if HashMap.containsValue(recordNum)" I assume you mean that after this check, your thread uses wait() to allow the cpu do other things until another thread calls notifyAll(), right? ...
- Yes, the thread does use wait and calls notifyAll() once the existing lock has been released.
...I tested with unreferenced and it gets called after about fifteen minutes or so
- I let the app run for over 20 minutes and the lock still wasn't released. I'll review my code again to be certain there isn't an error.
How often will it happen that two clients want to lock the same record at nearly the same time and one of them crashes?
- It doesn't have to be simultaneous. If ClientA crashes after locking Record1 and unreferenced() hasn't been executed, ClientB could request the lock on Record1 15 minutes later and will still be waiting for the lock to be released. Okay, the assumption is that unreferenced() will be called to perform code that unlocks the record that ClientA locked before crashing. That said, my question then becomes how do you circumvent the dependency on the unreferenced method to perform the unlocking? [ June 04, 2003: Message edited by: Christian Garcia ]
Joined: May 03, 2003
Why do you want to circumnavigate this dependency on unreferenced to unlock the record? Since unreferenced is indeed called (not sure why yours isn't), you can unlock there and be protected from the most dangerous case of records being locked for days at a time. The reason I'm not worrying about this is that for my assignment (hotels), I lock, update, and unlock in sequential statements. I don't have the client locking a record, then waiting for user input, which could be indefinite and offer time for crashes. The odds of a crash in between the locking and unlocking calls AND another user requesting a lock inside that unreferenced timeout period is so small that it's not worth the added complexity to worry about it much. If in your assignment, you lock and pause for input or something that could provide a greater chance of a crash, and you don't want the user to ever have to wait very long for a record, one option might be to check if a record is already locked before attempting to lock it. Your gui could inform the user that the record is currently being modified by another client and the user can try again in a few minutes or can select a different record. This puts the power in your client, which offers more control. You could automatically retry after a few seconds to check if it's still locked. You could offer an option to cancel. Etc. I just think all of that is not asked for in the assignment and adds to the complexity of the project. [ June 04, 2003: Message edited by: Perry Board ]
Joined: Jan 29, 2002
Perry, Good points. I agree with the thought that doing more than implementing the unreferenced method isn't necessary. I was more or less trying to discover if there are ways around it. That's a moot point now. The locking scenario I was using did indeed have a ClientA lock and have a ClientB try to lock on the same record. This was nothing more than a test. My implementation in the actual code will do as you described: lock, read, modify, unlock. Thanks for your responses.
Hi I am just wodering why is everyone using HashMap instead of HashTable to store the cookie and record number? whats the difference between the 2 and why is which one more preferred than the other one?
BEA 8.1 Certified Administrator, IBM Certified Solution Developer For XML 1.1 and Related Technologies, SCJP, SCWCD, SCBCD, SCDJWS, SCJD, SCEA,
Oracle Certified Master Java EE 5 Enterprise Architect