aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Unlock Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Soft Skills this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "Unlock" Watch "Unlock" New topic
Author

Unlock

Michael Morris
Ranch Hand

Joined: Jan 30, 2002
Posts: 3451
Hi all,
I have implemented my lock method by storing locked records in a HashSet. If a record is currently locked I call wait(). If a database lock is requested (record == -1) I set a boolean to true and once again call wait() if the Hash is not empty. If the aforementioned boolean is set, no more locks are granted so that the Hash can eventually empty so the database lock can be granted. Of course I throw an IOException on an invalid record request. No problem (I hope )
Now the problem comes in with unlock. One of the requirements is to ignore the unlock request if the client does not own the lock. This implies that we need to track who owns each lock. The easiest way to do that (as I see it) is to use a static long (for a unique ID), change my HashSet to a HashMap using the record number as the key and the unique ID as the value. Then tracking who owns the lock is accomplished but at the expense of changing the signature of lock() to return a long (so the client knows its ID) and unlock to accept the unique ID along with the record position.
Is there a better way to do this?
Thanks in advance
Micheal Morris


Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius - and a lot of courage - to move in the opposite direction. - Ernst F. Schumacher
Bal Sharma
Ranch Hand

Joined: Sep 19, 2001
Posts: 273
Hello Michael:

I did not keep track who own the lock in my project.
I just checked if record # exist or not in the HASH_SET. I mean unlock method unlocks the requested record. But ignores if the caller does not have a current lock on the requested record. Following is sample code.

There are multiple way of doing same thing. Some used tracking mechanisium who owns the each lock and ran extra mile changing signiture with unique ID. Extra work, more thought, more code. That is super. Some lazy guy like me never bothered. Who cares who wons the lock. Easy going, right! Bottem line is to save project from being dead lock. That is the main objective of this project, I think. You know what! even I did not use boolean true or false to check database/record locked or not. If HASH_SET does not contain a record on it, come'on YOU ARE WELCOME lock it. If it does, wait until it is unlocked.
For unlocking process, see weather it is locked or not. If it is locked unlock it, otherwise SMILE AND SAY you cannot unlock mam! you did not have lock before.
Hope it helps. -Bal
Laudney Ren
Ranch Hand

Joined: Jan 06, 2002
Posts: 111
Bal:
I have some questions for you.
In your unlock codes, you simply check whether the record has already been locked by seeing whethre the recordID is in the HashSet. If not, simply print some words and return. If yes, you unlock it.
But Morris' problem is that you don't make sure you are unlocking some record locked by you!!! If thread A locks record 1 and is doing some work, thread B can unlock record 1 prematurely, which violates synchronization requirement.
Possible solutions:
1. Like what Morris has done, use HashMap to save who has locked one particular record. But how you generate the unique long is more or less a problem
2. Use some ways (such as encapsulate commands in a object) to make sure no thread will call unlock without calling lock first.
-- Laudney


" Veni, vidi, vici "<br />" I came, I saw, I conquered "
Bal Sharma
Ranch Hand

Joined: Sep 19, 2001
Posts: 273
Hello Laudney:

... 2. Use some ways (such as encapsulate commands in a object) to make sure no thread will call unlock without calling lock first.....

I did exactly same what you are talking. I had a method name lockRecordOrDatabase(). It was responsible for locking business. Let me show you how did I use it.

See, there is sequence if you wanna modify a record you got to follow lock, read, modify, and unlock process. If naughty client wanna give a try unlock method without locking it. He/she should have some message, right! The message comes from unlock method for this problem.
Hope it mke some sense. -Bal
Laudney Ren
Ranch Hand

Joined: Jan 06, 2002
Posts: 111
Hi, Bal:
What you are doing is quite right.
-- Laudney
Michael Morris
Ranch Hand

Joined: Jan 30, 2002
Posts: 3451
Hi Bal & Laudney,
I see your point Bal and I am all in favor of keeping it simple and not changing signatures of the provided code.
Laudney, to make a unique ID is pretty simple. You just declare a private static long, set it to some starting point (0 is fine) and increment on all successful locks. You could test for Long.MAX_VALUE and reset to 0 if that occurs but that is probably unnecessary.
Thanks Guys,
Michael Morris
Adam Caldwell
Greenhorn

Joined: Mar 27, 2002
Posts: 17
If you assume that lock and unlock are done in the same thread, then the simplest way to keep track of whether or not you currently have the lock is to use Thread.currentThread() to obtain a Thread object for yourself and then save that away on the lock() and then make sure on the unlock() make sure that LockOwner(id)==Thread.currentThread()
Michael Morris
Ranch Hand

Joined: Jan 30, 2002
Posts: 3451
Hi Adam,
I hadn't thought of that. That is a good idea, but I was thinking about using a Thread pool for efficiency. That should still work though provided that the worker threads complete full transactions before starting new tasks.
Thanks for the input,
Michael Morris
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17260
    
    6

If you assume that lock and unlock are done in the same thread, then the simplest way to keep track of whether or not you currently have the lock is to use Thread.currentThread() to obtain a Thread object for yourself and then save that away on the lock() and then make sure on the unlock() make sure that LockOwner(id)==Thread.currentThread()

If you are using RMI, you cannot guarantee that the client will always be using the same thread. So this won't really work.
Mark


Perfect World Programming, LLC - Two Laptop Bag - Tube Organizer
How to Ask Questions the Smart Way FAQ
Michael Morris
Ranch Hand

Joined: Jan 30, 2002
Posts: 3451
Hi Mark,
Thanks for pointing that out. Do you suggest that I just assume that any request to unlock a particular record is by the current owner of the lock?

Michael Morris
xiaoma wang
Ranch Hand

Joined: Mar 04, 2002
Posts: 74
hi,Michael:
Following is from Mark's comment concerning my question. Hope it will make you clear the design.
"Nico, one of the requirements for the Server was an interface that implements all the public methods of the Data class. What this really does, besides make it nice to switch between local and remote mode. It also de-couples the Data class from everything. the data class know nothing except how to read/write/modify the db.db file.
So by binding the Data class into RMI, you have to rely more on that Data class to handle more things. First you have to change the signatures of all the methods, and also have it extend UnicastRemote. Not really a good design there.
What xiaoma is doing is taking a factory class called ConnectionFactory and it has a reference to the one and only instance of the Data class. It also has a method called getConnection(). This method creates a Remote object that resides on the server machine, and has a one to one relationship with the clients. Each client has it's own Connection object to service it's needs. When the getConnection method creates this class it passes a reference to the Data object via it's constructor.
Mark"
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Unlock