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


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "lock/unlock & synchronized" Watch "lock/unlock & synchronized" New topic
Author

lock/unlock & synchronized

ruilin yang
Ranch Hand

Joined: Feb 25, 2001
Posts: 334
Please help. I am confused.
With the lock/unlock methods implemented, then I should remove the key word "synchronized" from the methods in Data class, such as, getRecord, find, add, modify, etc. In this way, these methods can be accessed concurrently by other threads to work on unlocked records.
I my understanding is correct ? Please comments.
Thanks
Ruilin
Paul Anilprem
Enthuware Software Support
Ranch Hand

Joined: Sep 23, 2000
Posts: 3314
    
    7
No, lock and unlock operations are needed to support a "business rule" ie. if two clients try to modify the same record the result should be sensible. A call sequence of lock, read, modify, unlock will make sure that only one client modifies the locked record at a time. But it will allow other clients to modify other records. Locking a record (by calling lock() ) does not prevent multiple threads from modifying the file. (It prevents multiple clients from modifying the same record).
The individual methods (like modify(), write() etc. ) are doing an entirely different job. They are actully writing the data to the file and so they have to be synchronized because if multiple threads try to modify the file at the same time, the file will be screwed up!

HTH,
Paul.
------------------
Get Certified, Guaranteed!
(Now Revised for the new Pattern)
www.enthuware.com/jqplus

Your guide to SCJD exam!
www.enthuware.com/jdevplus
Try out the world's only WebCompiler!
www.jdiscuss.com


Enthuware - Best Mock Exams and Questions for Oracle/Sun Java Certifications
Quality Guaranteed - Pass or Full Refund!
ruilin yang
Ranch Hand

Joined: Feb 25, 2001
Posts: 334
Paul,
Thanks. I thought as long as you lock a record, you can guarantee no data cruption.
Is my understanding is correct as following ?
Lock records protects against multiple users to concurrent access the same record.
Synchronized methods/code block/classes is for againsting the same user with seccessive use of methods in case one method excution in the middle of the way working with data and calling another method to access the data.
Please comments and thanks.
Ruilin
Alex Zhang
Ranch Hand

Joined: Apr 19, 2001
Posts: 68
I don't know really I am right to have this idea or not
I have a hashtable which use the key of the record for the hashtable key and I use this record key(String) for the lock to apply synchronization within the lock method
I just think if I lock the record no one can use this record concurrently
and I start my modify method with no fear of other modifying the same record
So I have not used the synchronized key word or synchronize block throughout the modify method
Would anyone tell me if there is any problem and error with this
and how to do it better?
R Bischof
Ranch Hand

Joined: Feb 13, 2001
Posts: 48
Simple example:
Client A locks record 1, client B locks record 2. That's OK.
Client A starts modifying the record. At first this physically moves the file pointer to the position of record 1.
Now client B begins modifying record 2. Since modify is not synchronized the client is allowed to enter that method although client A is currently there. That physically moves the file pointer to position of record 2.
Now client A is continued and writes the modified record 1 to the position of record 2.
Client B continues and writes record 2 behind this position and the DB file is corrupt.
Since multiple threads are virtually executed at the same time you have to ensure that only one thread can alter the position of the file pointer. This is done by synchronizing on the modify method (and others like getRecord, etc).
HTH
Rainer


Rainer<br />SCJP, SCJD, SCWCD
xiaolin wu
Greenhorn

Joined: Jan 09, 2001
Posts: 11
hi, Rainer and Paul:
I am confused too, please clarify.
I use RMI for communication. multiple clients can access the same remote object. remote object delegate the request to a Data object. most methods in Data object are synchronized ( such as getRecord(), modify(), provided by Sun.) so there is only one remote obj. and Data obj. when clients access Data's synchronized methods, the whole Data obj. is locked. why we need lock() and unlock() on indivual recoeds. thank for your thought!

xiaolin wu
ruilin yang
Ranch Hand

Joined: Feb 25, 2001
Posts: 334
Xiaolin,
Different user will initiate different objects of Data class. Therefore, these users can access the database concurrently. That is why you need lock/unlock the database/its record.
Good luck,
Ruilin Yang
xiaolin wu
Greenhorn

Joined: Jan 09, 2001
Posts: 11
Ruilin:
thank for your reply. I may not state it clearly.
the structure of my program is like this:
client obj: Naming.lookup (remoteData)-> get a reference to remote obj.
server obj instantiate a remoteDataImpl obj and Naming.rebind("remoteData", remoteDataImpl);
Now multiple clients can get a reference to the same remoteDataImpl obj.
remoteDataImpl obj instantiate a private Data obj, and send all request to that Data obj.
there is no other way to instantiate a Data obj.
I can understand that the synchronize Data obj can provent clients mess up db.db file. I couldn't figure out why I need lock/unlock on record. unless I need to instantiate multiple server obj. which I don't think is necessary.

please point out the disadvantage of this structure, and could you tell me what your program looks like.
thank you very much!

xiaolin wu
ruilin yang
Ranch Hand

Joined: Feb 25, 2001
Posts: 334
Xiaolin,
Are you sure: multiple clients can get a reference to the same remoteDataImpl obj.
I thought each client will invoke a different remote object even through the same name binding. Is this the mechanism of RMI or not?
I am not sure about my understanding. This is the critical point to understand RMI. You may right when server starts, only one object is created for multiple clients.
If you implement the server class with multiple threads, then I believe you will get multiple remote objects. In this case you definitely need lock/unlock for the database.
You may be right: if you do not implement your server class (making the name binding) with multiple threads, then you may not need lock/unlock. In this case synchronized methods will be sufficient to prevent data cruption.
Please comment more. I like to make sure.
Ruilin
xiaolin wu
Greenhorn

Joined: Jan 09, 2001
Posts: 11
ruilin:
I am not 100% sure, but I think it is. check the following link
http://developer.java.sun.com/developer/onlineTraining/rmi/RMI.html#Comparison
for comparsion of local and remote object creation. I did not use Remote Object Activation.
I am more confused. let's ignore server threads. how many Data objects in your program? let's say multiple clients and one Data object, that is many to one relationship. if one client access a synchronized methods of Data obj. other clients can not access the same object. why do we need lock/unlock?
if we have multiple clients and multiple Data obj ( created by server, one Data object per client). each client have it's "own"
Data object. why da we need synchronize and lock/unlock to Data obj. at all?( to control db.db file access, we do need synchronize Data class).
gurus, please help!

thank you

xiaolin wu
Ravikiran Choppalli
Ranch Hand

Joined: Nov 18, 2000
Posts: 49
This is an interesting question.
If anybody could help clear this, that would be great.
Ravi


Thanks,<BR>Ravikiran<BR>rkchoppalli@yahoo.com
Michael Scott II
Greenhorn

Joined: May 23, 2001
Posts: 2
The way I understand it to work is like this.
On the server-side there would be a remoteDataFactoryImpl which had a reference to the Data object and was binded to the name server. The client would do a look up on the name server for this factory. Once the client had a reference to the factory it would call a method like create() which would instantiate a remoteDataImpl, passes it a reference to the Data object, and pass the reference back to the client. The remoteDataImpl is export but not binded to the Name server. Therefore it is a remoteObject but you can't do a look up in the name server to find it. Once you have a reference to remoteDataImpl you make all request on the Data object though it.
There would be one remoteDataImpl object for every client.
Now I just started on the developer yesterday but I think you need the lock and unlock methods for:
I go in as a client and look up a record for what ever reason. I might be using the information on that specific record to do something if I don't lock that record then someone else can go in and change the information in the record. therefore the information inwhich I was viewing is incorrect, as well as anything I did with that information.
The lock and unlock methods are to lock a specific record. Therefore you need the lock and unlock methods.
Look at it from this perspective I want to book a flight and I need I tell someone we have one more seat and I can get it for him. If I don't lock that record someone else can come alone who types faster and steal that person seat which I just promised him.
The synchronized is to provent someone the move the file pointer in the middle of some one reading or write to the file.
I hope that helps you guys.
Mike
xiaolin wu
Greenhorn

Joined: Jan 09, 2001
Posts: 11
hi, mike:
thank for your response!
As to my first question. you definitely can implement the remote object in that way. I mean you can create a remoteDataFactoryImpl obj and bind it to name server. when client look up, he get a reference to remoteDataFactoryImpl and call remoteDataFactoryImpl.create() to get a remoteDataImpl obj.
now the question become if there is one remoteDataFactoryImpl object for every client or not.
as to lock/unlock method, you are absolutely right. book flight is a multi-step process(read record, check seat availablity, modify and write back to db.db file), we need lock() to ensure the consistence of record.( synchronize bookflight() is against Sun's requirement, which require concurrently access Data obj.) I did not see that at beginning, chua pointed out to me, and now you confirm it.
thank for sharing your knowledge with us!
xiaolin
Michael Scott II
Greenhorn

Joined: May 23, 2001
Posts: 2
Your welcome.
You have the right idea, all but the end. There is only one remoteDataFactoryImpl and it sits on the same machine as the data object. It would make sense to have more than one.
No problem helping!
Mike
Mike Wiegand
Greenhorn

Joined: May 30, 2001
Posts: 15
Hello,
this may seem like a really stupid question, but how many copies of db.db are there? Is there one copy for running locally and one that exists on the remote server also? Or, does the remote access point to the same db.db as the local version. It hooks up to the local version using a URL. I'm kinda confused about this...and other things.
Any insight would be greatly appreciated!
Thanks a lot.
Mike
ruilin yang
Ranch Hand

Joined: Feb 25, 2001
Posts: 334
You have two choices:
1) one copy of db.db stored at the server side, with two copies of client programs (e.g. GUI's for local and remote modes);
2) two copies of db.db one at server and one at client side, with only one copy of client programs.
For the choice 1), you will have to have two copies of client programs: one copy at client for remote access to database and other copy at server for local access to database. When you run the local mode you will start the system at the server side. When you run the system in remote mode you will have to run at the client side.
For the choice 2), you will have 2 copies of db.db, but with one single copy of client programs. You will run the system always at the client side. The client have a choice for remote/local mode at the beginning of running the program (e.g. 1st GUI).
The advantage of the 1) choice is that you do not need to synchronize db.db. The inf allways consistent. The booking confirmation is instant. But you have to run the two modes from different sides (client and server). This means that client do not always have access to the system. When the system is not available in network mode you have to assume that a client has to make call to contact server side to ask a booking.
The advantage of the 2) choice is that the client always have access to the system and you can run the system from only client side for both modes (remote/network). You only need one copy of clent programs. Therefore, maintanence of the system is simple. However, you have to periodically sychronize the two copies of db.db. The client can not get instant confirmation for booking when the system is running in local mode. In this case the client can only get confirmation for booking later when the system is running in network mode.
I am not sure what Sun want us to do .
Anybody have some insight on this please make comments.
Ruilin
Mike Wiegand
Greenhorn

Joined: May 30, 2001
Posts: 15
Hi Mike,
I'm confused...again. What exactly does this buy you?
For remote access, my thoughts go something like this...
if remote connection, do the lookup to get a reference
to a wrapped instance of the Data class on the server.
Then, from the client, simply call the desired methods using this reference. I guess for lock/unlock, a mechanism must be
installed to determine what client locked the Data object.
Thanks
Mike
Originally posted by Michael Scott II:
The way I understand it to work is like this.
On the server-side there would be a remoteDataFactoryImpl which had a reference to the Data object and was binded to the name server. The client would do a look up on the name server for this factory. Once the client had a reference to the factory it would call a method like create() which would instantiate a remoteDataImpl, passes it a reference to the Data object, and pass the reference back to the client. The remoteDataImpl is export but not binded to the Name server. Therefore it is a remoteObject but you can't do a look up in the name server to find it. Once you have a reference to remoteDataImpl you make all request on the Data object though it.
There would be one remoteDataImpl object for every client.
Now I just started on the developer yesterday but I think you need the lock and unlock methods for:
I go in as a client and look up a record for what ever reason. I might be using the information on that specific record to do something if I don't lock that record then someone else can go in and change the information in the record. therefore the information inwhich I was viewing is incorrect, as well as anything I did with that information.
The lock and unlock methods are to lock a specific record. Therefore you need the lock and unlock methods.
Look at it from this perspective I want to book a flight and I need I tell someone we have one more seat and I can get it for him. If I don't lock that record someone else can come alone who types faster and steal that person seat which I just promised him.
The synchronized is to provent someone the move the file pointer in the middle of some one reading or write to the file.
I hope that helps you guys.
Mike

Karl Fu
Ranch Hand

Joined: Mar 26, 2001
Posts: 41
Micheal,
I understand your approaches to instantiate the Factory and Implementation object..pretty much like an EJB instantiation.
So if i understand it correctly, if there is 10 concurrent user, then there are 10 Impl object reside on the server side.
However, what I don't get is how to obtain a reference of client ID on the server without changing the signature of lock and unlock. Since every client (represented by impl object) has the same data object within it, and the lock method is within the data class. if no parameter is passed into the lock method , how do we identified which client is calling the lock method ? I was thinking of using the key word "this".....but it doesn't seems to work since all concurrent user have the same data object within their individual impl object, calling "this" will always refers back to the same object, how do we resolve this without modifying the signature ?
Thanks in advance
Karl
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by Karl Fu:
[...] So if i understand it correctly, if there is 10 concurrent user, then there are 10 Impl object reside on the server side.
However, what I don't get is how to obtain a reference of client ID on the server without changing the signature of lock and unlock. Since every client (represented by impl object) has the same data object within it, and the lock method is within the data class.

You have an object per client. That object is all the client ID you will ever need. Yes, the data class has a lock method which doesn't know about clients - but ask yourself: should the (un)lock method, in that class, actually implement any of the locking semantics? Or can you safely leave those methods empty?
- Peter
Rick Fortier
Ranch Hand

Joined: Jun 04, 2001
Posts: 147
Peter -
You have an object per client. That object is all the client ID you will ever need.
I don't find this to be true. On the server I have the following classes:
FBNServer - which provides the exported interface to Data
FBNStart - which registers the server in the registry
Data - which knows how to talk to the random access file
LockManager - which handles all of the locking/unlocking
DataInfo & FieldInfo
As an expiriment I put a static variable in each class and incremented the counter each time its constructor was called. The only objects which ever got above 1 were DataInfo and FieldInfo.
So when the client calls the lock read modify unlock sequence there is no object created for this client until the read. The read instantiates a DataInfo object for each client. Since I dont have this object until after lock(), I cannot use it to control the lock/unlock mechanism.
I then put in trace code which printed out the thread information during each lock/unlock call using mythread.toString(). What I found was that while each client did not create any new objects during lock() they did each have their own thread.
From my testing, the thread used during lock() always was the same thread as the unlock() (even though Sun states that this is not guaranteed). So except for the fact that Sun has made this statement, I do not see any object I could use in my LockManager collection (HashMap).
Could you give more information?
And yes, in my Data class I don't implement the lock and unlock methods there. I do this in my LockManager (singleton) class.
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by Rick Fortier:
Peter -
I don't find this to be true. On the server I have the following classes: [...] The only objects which ever got above 1 [instance] were DataInfo and FieldInfo.

Now I'm confused. I thought you said you had one implementation object per client, more or less along the lines described by Xiaolin above. In that case, that object will do a fine job of identifying the client.
The description you're giving sounds like you have one FBNServer object serving all clients. If so then, yes, the lock/unlock methods it exposes will probably need an additional argument.
- Peter
Karl Fu
Ranch Hand

Joined: Mar 26, 2001
Posts: 41
Thanks Peter for you help, i got a much beter idea about the locking mechanism now.
I think i got misdirected by the source code provided ...they put the lock and unlock method in the Data class and this makes me assume the entire locking mechanism could be done within the Data class alone.
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by Karl Fu:
I think i got misdirected by the source code provided ...they put the lock and unlock method in the Data class and this makes me assume the entire locking mechanism could be done within the Data class alone.

This is a bit confusing. One of the important steps in doing the Developer certification is to realise that the Data class provided is actually two things: an interface for clients to use, and a local implementation for that interface. Most of the people I know who've done the certification end up separating the Data interface from its implementation. (Not that that is the only way of doing it).
- Peter

[This message has been edited by Peter den Haan (edited June 10, 2001).]
Jim Dong
Greenhorn

Joined: Jul 09, 2001
Posts: 12
Peter,
do you mean that people rip the original Data class and put it into a class and an interface? Please clarify a bit.
Thanks.
[This message has been edited by Jim Dong (edited July 10, 2001).]
Javini Javono
Ranch Hand

Joined: Dec 03, 2003
Posts: 286
Originally posted by Paul Anil:
No, lock and unlock operations are needed to support a "business rule" ie. if two clients try to modify the same record the result should be sensible. A call sequence of lock, read, modify, unlock will make sure that only one client modifies the locked record at a time. But it will allow other clients to modify other records. Locking a record (by calling lock() ) does not prevent multiple threads from modifying the file. (It prevents multiple clients from modifying the same record).
The individual methods (like modify(), write() etc. ) are doing an entirely different job. They are actully writing the data to the file and so they have to be synchronized because if multiple threads try to modify the file at the same time, the file will be screwed up!

HTH,
Paul.


Hi,
Tonight I did a search on "lock()" and have been reading through some old postings.
I'm trying to understand what it is I'm missing; that is, why do the majority of people
think a locking scheme (using a Map for instance) is important?
I think that the above article may have answered my questions; not that others have not
answered them before; but, because this is a new topic area for me, I have to continually
look at the topic before I begin to understand it.
Here is my understanding of why people generally would non-trivially implement
a record locking scheme; and, for this discussion, assume that you are accessing
a random access file on disk (you are not holding the file in an object in memory).
Perhaps it comes down simply to this: a multi-threaded computer processor gives the
impression that many things are happening simultaneously. Similarly, if you lock
the whole database, instead of one record, then if there are enough clients, each client
starts to feel a delay which is overly long (and at some point unacceptable). Thus,
by implementing a record locking scheme, any randomly chosen client appears to
be responding faster.
Is this the motivating factor behind using a record locking scheme?
And, if this is the motivating factor, in general, could it be proven; that is, with
100 clients, the average delay to get a response is 0.01 seconds,
500 clients, the average delay to get a response is 0.5 seconds,
1000 clients, the average delay to get a resposne is 1 second,
and so forth.
I guess what I'm saying is, there has been not much mention of just how much
of a load is going to be on the server. If I only have 100 clients, I may not
be able to justify the complexity that record locking adds. But, if I have
100,000 clients, it may be strongly justified.
Thanks,
Javini Javono
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11481
    
  94

Hi Javini,
You are assuming that only the clients that you write will ever access the server. And as such, only the one business method you decided the customer will get is the only one that can ever be used. If ever the customer has any other business requirement, a brand new method will have to be written to go onto the server, and then the clients will have to be modified to work with the new version.
So lets add a simple business case: the user wants to book multiple hotel rooms in one transaction. If they cannot get hotel rooms in every city they visit, they do not want any of them.
This can easily be added to the server. And as long as you still only have one client doing any database accesses at any one time you still do not need the lock methods.
But what happens if 10 clients all try and book 10 hotel rooms. The 10th client is now waiting 90 times longer than if they had done a single transaction.
You picked some numbers out of the air for your example: 0.01 seconds per transaction. But the server software could initially be put onto a slow, overworked machine where each transaction takes 1 second to complete (OK, I am also making up numbers ). Now that last client is waiting nearly 2 minutes for their booking - and there are only 10 clients.
One of the big reasons for allowing record locking is that it allows concurrent processing by multiple clients. This is the major reason for having a server in the first place. You keep trying to limit the server to only allow one connected client to work at any one time. This to me is counter intuitive.
Regards, Andrew


The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Peter Yunguang Qiu
Ranch Hand

Joined: Nov 22, 2003
Posts: 99
--No, lock and unlock operations are needed to support a "business rule" ie. if two clients try to modify the same record the result should be sensible. A call sequence of lock, read, modify, unlock will make sure that only one client modifies the locked record at a time. But it will allow other clients to modify other records. Locking a record (by calling lock() ) does not prevent multiple threads from modifying the file. (It prevents multiple clients from modifying the same record).
The individual methods (like modify(), write() etc. ) are doing an entirely different job. They are actually writing the data to the file and so they have to be synchronized because if multiple threads try to modify the file at the same time, the file will be screwed up!
Suppose only there is one instance of Data class.
Q1:
Because read / modify methods are synchronized, it guarantees only one client can access (read or write) the file at one time. So, if the lock/unlock are not useful?
--- Since multiple threads are virtually executed at the same time you have to ensure that only one thread can alter the position of the file pointer. This is done by synchronizing on the modify method (and others like getRecord, etc).
Q2:
if the file pointer is synchronized, it has the same effect as to synchronize read/write methods, so lock and unlock are not needed?
Any conmments?
Peter
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11481
    
  94

Hi Peter,
The lock()/unlock() mechanism are used for a totally different purpose than the synchronization on methods within the Data class.
If you are reading / writing the file directly, then your read method will look something like:

If that method (or a block within that method) is not synchronized, then two threads could operate on it at the same time. So thread A could seek to record 5, then thread B could seek to record 8, then thread A could read a record - but then it has just read record 8 instead of record 5 .
So you need to ensure you have thread safe access to file operations, and the common way of doing that is by using synchronization.
The lock()/unlock() methods have a totally different purpose. When you book a record in a multi user server, you should:

We now have a similar problem with multiple clients running this method (either because you have a multi threaded server or because you have your booking method on the client side). Client A starts validating record 5, Client B starts validating record 5, Client A then books record 5, Client B then books record 5.
If you booking method is on the server, then you could synchronize that method. That would mean that only one client could do an update at any one time.
The problems with that are:
  • You may not want your booking method on the server (see the thread "Should lock methods be callable by the client" for reasons why you might not want to do that).
  • If there is complicated processing that needs to occur during the booking phase, then you will be blocking clients unnecessarily.


  • If you can lock the record prior to validating, and then unlock it again after booking, then multiple clients can be doing bookings simultaneously.
    Regards, Andrew
    Peter Yunguang Qiu
    Ranch Hand

    Joined: Nov 22, 2003
    Posts: 99
    We now have a similar problem with multiple clients running this method (either because you have a multi threaded server or because you have your booking method on the client side). Client A starts validating record 5, Client B starts validating record 5, Client A then books record 5, Client B then books record 5

    Client B have to book record 5 after Client A done its booking, because the booking mechnism is synchronized. When client A doen, record 5 is not OK for booking, so client B cannot book it. It seems there is no need to lock record 5 as long as the booking methods and read/wirte methods are synchronized and only one instance of file access class.
    Peter
    Andrew Monkhouse
    author and jackaroo
    Marshal Commander

    Joined: Mar 28, 2003
    Posts: 11481
        
      94

    Hi Peter,
    But if you do that, you are loosing the advantages of having a multi threaded / multi user database.
    Right now we have a very simple concept: a record is either booked or not booked. So our booking method can be quite simple:

    But lets consider a more complex booking requirement:

    Now if you have synchronized the entire booking() method, then that means that only one thread can do all those steps at any one time. I think a turaround time of 5 seconds for all that processing is not inconceivable. So you can only ever do one booking every five seconds.
    Now consider the same set of processes if you do not synchronize the methods - if you use the lock() and unlock() methods instead. In that case, the method to check that the record is still available, and the method to update the record will both have to be synchronized. But every other method can be run simultaneously in multiple threads. Each individual booking may still be taking 5 seconds, but you can process hundreds of those bookings in that same 5 seconds.
    Whenever you synchronize bits of code, you should try to do so for as short a time as possible, and over the smallest bit of code that is necessary. So you should only synchronize on the methods that are dealing with the physical file access and the methods that are involved in granting / releasing locks. Everything else can (and should) be non synchronized.
    Regards, Andrew
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: lock/unlock & synchronized