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


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "NX: About Locking" Watch "NX: About Locking" New topic
Author

NX: About Locking

Flavio Nobili
Ranch Hand

Joined: Jan 28, 2004
Posts: 58
Hello to all,
I've read some posts about record locking, and one thing that I could see is that there are two ways of thinking in locking. One is using lock methods just at the moment that a client is booking, like the following:
lock()
read()
update()
unlock()
The actions will be done at once, just to be sure that another concorrent thread will not be able to access this locked record. But, in fact, it can be done by using synchronized methods, doesn't it?
Another way is locking when a client is going to book but he has not confirmed yet (when the user clicks on the book's button and a dialog window asks him to enter the client number). At the moment that he is booking a room, another client can't access the room's record to book it too. Therefore, the code would be like this:
lock()
read()
update()
unlock()
Note the space between the two actions. The unlock method can be called a lot of time after lock is called, and not in an atomic action like the first way. But, on the other hand, I can't use wait/notify in this way.
My question is: Which is the correct?

Regards,
Fl�vio.
[ February 07, 2004: Message edited by: Fl�vio Fran�a ]

Java Developer
SCJP, SCJD, SCWCD, SCBCD
Satish Avadhanam
Ranch Hand

Joined: Aug 12, 2003
Posts: 697
-------------------------------------------------------------------------
Hello to all,
I've read some posts about record locking, and one thing that I could see is that there are two ways of thinking in locking. One is using lock methods just at the moment that a client is booking, like the following:
lock()
read()
update()
unlock()
The actions will be done at once, just to be sure that another concorrent thread will not be able to access this locked record. But, in fact, it can be done by using synchronized methods, doesn't it?
Another way is locking when a client is going to book but he has not confirmed yet (when the user clicks on the book's button and a dialog window asks him to enter the client number). At the moment that he is booking a room, another client can't access the room's record to book it too. Therefore, the code would be like this:
lock()
read()
update()
unlock()
Note the space between the two actions. The unlock method can be called a lot of time after lock is called, and not in an atomic action like the first way. But, on the other hand, I can't use wait/notify in this way.
My question is: Which is the correct?

Regards,
Fl�vio.
---------------------------------------------------------------------------
Hey Fl�vio,
I think if we use the first approach of locking, i.e. atomic, then if other threads want to obtain a lock, they will know immediately whether the room is available or not.(Not wasting any cpu cycles by other threads, waiting to obtain a lock)
On the other hand, using the second approach if we lock the record and unlock it after a while(not as atomic), then other threads might have to wait and consume cpu cycles right.
I am not sure if I am right. Please correct me. Thanks.
George Marinkovich
Ranch Hand

Joined: Apr 15, 2003
Posts: 619
Hi Fl�vio,
Originally posted by Fl�vio Fran�a (bold parts added by me):
Option 1:
getCustomerID()
lock()
read()
update()
unlock()
Option 2:
lock()
read()
getCustomerID()
update()
unlock()
My question is: Which is the correct?

Like most things this is a trade-off that involves pros and cons.
Option 1:
Pro: The record is locked for the minimum period of time possible. This results in a higher level of concurrency for booking operations (that is, more booking operations could be performed per time period than would be the case with Option 2).
Con: Obtaining the customer ID is optomistic. The user must enter the customer ID before he really knows that he will be able to book it. If the records in the JTable are stale it's quite possible that the user will attempt to book a record, enter the customer ID and then be told that sorry the record is already booked. At this point the user is apt to think it was pretty stupid for the program to ask him for his customer ID when it should have known the record he was trying to book was already booked.
Option 2:
Pro: When the program asks the user for his customer ID there's no question that the user is really going to be able to book the record. If the user's record in the JTable was stale and during the booking process it is discovered that the record had already been booked by another user, then the user will never be asked for his customer ID. Obtaining the customer ID in this option is pessimistic; if the user isn't going to be able to book the record, then the application won't ask him for his customer ID.
Con: The record will certainly be locked for a longer period of time than under Option 1. It may be a matter of seconds longer or in the worst case it could be forever (at least as long as the server is running). This has a negative effect on the concurrency of booking operations. More booking operations can be performed by Option 1 than Option 2 in the same period of time.
Both of these options can use wait and notify. If you wait for 1 second or 10,000 seconds the waiting thread still uses the same number of CPU cycles, namely zero.
If you go with Option 1 you value the higher concurrency (which may never be significant in practice) over the inconvenience of having users enter their customer ID's when in fact they will not be able to book the record (which will only happen when there is a stale record). You may decide that there will never really be that many stale records. Remember a stale record indicates that some client has booked a record and some other clients haven't updated their JTables to pick up this update. So if you believe there will never really be that many stale records then one of two things is true. One, you believe that the clients will be doing frequent searches so their JTable records are never very stale (of course if the user is constantly having to search for records so their JTable doesn't get stale, does that really contribute to better system performance?). Or two, you believe that there will not be that many records booked, so as a consequence there won't be that many stale records (of course if not that many records are being booked, why exactly do you need the increased concurrency of Option 1?).
If you go with Option 2 then you're saying you value the user's time (which is wasted when the user enters a customer ID when they will not be able to book that record) more than you do an increase in booking concurrency (which in practice may not be apparent to the user).
Obviously I have a personal opinion on which option I would choose (and that opinion is probably a minority one). In this case, we're talking about a single field. It's really not incredibly burdensome for a user to enter a single customer ID. However, imagine that instead of a single field, the user had to fill out a form of fields. To do all this work and then be told that it was effectively wasted is not a good strategy for creating happy users in my opinion.
Hope this helps,
George
[ February 08, 2004: Message edited by: George Marinkovich ]

Regards, George
SCJP, SCJD, SCWCD, SCBCD
Satish Avadhanam
Ranch Hand

Joined: Aug 12, 2003
Posts: 697
Hi George,
Thanks for the detailed explanation. Really appreciate that.
Thanks.
Flavio Nobili
Ranch Hand

Joined: Jan 28, 2004
Posts: 58
Hi George,
Thanks for your detailed analysis.
But one thing is not clear to me about option 1: Why should I use lock/unlock methods if I can use a sysnchronized method instead?
Book method using lock/unlock:

Synchronized book method:

Don't they both do the same?

Regards,
Fl�vio.
[ February 08, 2004: Message edited by: Fl�vio Fran�a ]
George Marinkovich
Ranch Hand

Joined: Apr 15, 2003
Posts: 619
Hi Fl�vio,
To discuss synchronization we have to know what is being synchronized. What is the context of your synchronized book method? In other words, with respect to what is it synchronized? Is the synchronized book method defined in the same class as the lock, read, update, and unlock methods? If so, are these other methods synchronized as well?
Method synchronization means that any of the synchronized methods within the same class cannot be executed simultaneously on the same object. Of course, the synchronized methods can be executed simultaneously on different objects. So this raises the following question about the class that implements the book method: how many objects of this class exist? What is the relationship between each client and an instance of the class implementing the book method? One-to-one? Many-to-one?
So the answer to the question "don't they both do the same thing?", is maybe yes and maybe no. It's not possible to answer definitely without understanding in what context the synchronization is taking place.
Hope this helps,
George
Flavio Nobili
Ranch Hand

Joined: Jan 28, 2004
Posts: 58
Hi George,
In my solution I have a class that handle the access to the database file (where I've put read, update, delete, find, lock and unlock methods), and another one that gives the methods to serch, book, etc. This class is the database class, that uses the first class to access the file. On the server we will ever have only one instance of these classes, that supports all client accesses. So, in my case, there is no reason to use the lock/unlock methods if I'm using synchronized methods. Am I right?
Regards,
Fl�vio.
Leo Tien
Ranch Hand

Joined: Sep 10, 2002
Posts: 156
Hi Fl�vio:
After read your topic, I think your db access layer is:
DBAdapter ----> Data ----> db.db
The DBAdapter and Data are all singleton, in the DBAdapter you wrap the Data method and support some business methods such as book, search and so on. But my question is, if your book method's implementation like this:

Did you wrap lock and unlock method in DBAdapter ??
a) If yes, then you must have another class that called from client and may be have one method like this:

because the book method in DBAdapter is synchronized, so you must select the first option above.
b) If not, where are you call lock/unlock method ?? If you will not call lock/unlock at all, how your server handle multiple concurrent requests and provide locking functionality??
Because in my assignment:
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....

Make sense??
[ February 08, 2004: Message edited by: Leo Tien ]
Flavio Nobili
Ranch Hand

Joined: Jan 28, 2004
Posts: 58
Hi Leo,
Yes, the lock and unlock methods are in the adapter. But, I've got to the conclusion that these methods are not usefull at all, because if I have a synchronized method to book, I don't need to lock any record.
I'm thinking in changing this solution by using a non-synchronized method to book, just to use the lock/unlock methods, but in a real situation I wouldn't do that.
Thanks,
Fl�vio.
George Marinkovich
Ranch Hand

Joined: Apr 15, 2003
Posts: 619
Hi Fl�vio,
Originally posted by Fl�vio Fran�a:
I'm thinking in changing this solution by using a non-synchronized method to book, just to use the lock/unlock methods, but in a real situation I wouldn't do that.

I think this is the classic debate between those who advocate a 2-tier solution versus those who advocate a 3-tier solution. Or to put it in other words, is it proper to expose the locking to the client or not? There are many threads that discuss the pros and cons or each of these solutions. Candidates from both schools have been succussful.
database operations (lock, unlock, read, etc.) <--> client
or
database operations (lock, unlock, read, etc.) <-->
business methods (search, book) <-->
client
Whether you expose the lock and unlock methods to the client will influence how you implement your locking solution.
Hope this helps,
George
Leo Tien
Ranch Hand

Joined: Sep 10, 2002
Posts: 156
Hi Flavio:
But, I've got to the conclusion that these methods are not usefull at all, because if I have a synchronized method to book, I don't need to lock any record.

I disagree with you. If you will not call lock/unlock at all, how your server handle multiple concurrent requests and provide locking functionality?? This is asked above,
In your solution, use synchronized method instead of lock/unlock, your server only handle one request in the same time. Alone this solution, in two tier design, like this:
----------------------------------------------------------------
client ---> besiness methods ---> network server ---> DBAdapter
----------------------------------------------------------------
Because of your DBAdapter is singleton, so all requests from client are blocked between "network server" and "DBAdapter". So only after one thread finish its operation(search, book, etc.), another thread can do its. This means that your server only can handle one request.
In three tier design, condition is same:
----------------------------------------------------------------
client ---> network server ---> besiness methods ---> DBAdapter
----------------------------------------------------------------
All requests are blocked between "besiness methods" and "DBAdapter".
But if use lock/unlock methods, the block is between "DBAdapter" and "Data";The first condition(don't use lock/unlock), the lock is on one operation(search, book, etc.), while the second condition(use lock/unlock), the lock is on one record or record container.
On the second one, the server can handle multiple requests, example, when one client is booking on record 1, at the same time, another client can do search oper and do book on record 2.
comment???
Flavio Nobili
Ranch Hand

Joined: Jan 28, 2004
Posts: 58
Hi Leo,
Yes, it's true. If my business' book method executes only one synchronized method in the DBAdapter to book a room, it'll not be executed concurrently. But then it's not a good idea to have a singleton DBAdapter. I'd better change it. Is it right?
Regards,
Fl�vio.
Leo Tien
Ranch Hand

Joined: Sep 10, 2002
Posts: 156
Hi Fl�vio:
I'd better change it. Is it right?

Mmmm....I feel this depend on your design. If you use singleton DBAdapter, I think you must call lock/unlock method in business methods, this is sun's requirement(do locking mechanism).
 
 
subject: NX: About Locking
 
Similar Threads
NX: cacheless design to keep things simple?
Passed SCJD - 366 /400
Multi-threading programming: we do not need lock() unlock() at all
lock/unlock & synchronized
Some details about my solution