aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes synchronized methods vs locking (e.g. update) 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 "synchronized methods vs locking (e.g. update)" Watch "synchronized methods vs locking (e.g. update)" New topic
Author

synchronized methods vs locking (e.g. update)

Jay Lin
Greenhorn

Joined: Apr 23, 2005
Posts: 3
Hi all,

I'm following Habibi's book pretty closely, and admittedly synchronization is not my strongest point. My question has to do with the purpose of synchronizing the entire method (let's say the update method, for example) of the database class, and then having clients lock before calling update and unlocking afterwards.

The difference between my implementation and the book's is that my database is a singleton, whereas in the book there can be multiple database objects for the same DB. But I'm still not entirely clear why both the method is synchronized and lock/unlocks are placed around the method. It seems to me that only one of those is necessary.

If two update threads are hitting the DB, isn't it true that if update is synchronized, one thread will have to complete before the other one starts? Therefore, what is the purpose of locking a record before updating it?

I am guessing that there IS a purpose and I just don't see it, so hopefully someone can enlighten me =) Thanks!
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11481
    
  94

Hi Jay,

This is such a frequently asked question that I should really add it to the JavaRanch SCJD FAQ. Maybe I will later (or if you want to do it, feel free ).

Most of the file operations require some synchronization, as they involve accessing a single shared resource. Even worse, they often involve two operations on that single shared resource, where the two operations must behave atomically. That is, you would normally perform a seek() and then a write(), however you do not want any other thread to perform a seek() between when you performed your seek() and when you perform your write(), otherwise you will end up writing in the wrong location within the file.

We will ignore for the moment the question of whether it is better to synchronize the entire update() method in Data class, or whether to just put the seek() and write() methods within a syncronized block.

So having somehow synchronized the access to the file, we still have a problem of two clients believing that a record is available, and both trying to update it. That is:
  • Client A checks that record 5 is avaialable
  • Client B checks that record 5 is avaialable
  • Client A updates record 5 with their client number
  • Client B updates record 5 with their client number
  • now client B has overwritten client A's booking

    This is where the logical record locking available through the lock() and unlock() methods of the Data class come in - in the above scenario, if client A had logically locked record 5 prior to checking availability, and client B had attempted to locally lock record 5 prior to checking availability, then client B would be blocked until client A had finished - no more problem.

    Regards, Andrew


    The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
    Jay Lin
    Greenhorn

    Joined: Apr 23, 2005
    Posts: 3
    Ah I missed a key point here, that the client may want to make logical queries on the database other than using only the methods provided by the Data interface (such as checking availability). I was going along with the (mistaken) notion that arbitrary Data queries (like update) can occur in arbitrary orders as long as individual queries are atomic, and everything would be okay. I didn't consider it bad to overbook, which of course should be avoided. Thanks for the answer, makes perfect sense now.
    Bob Nedwor
    hangman
    Ranch Hand

    Joined: Aug 17, 2005
    Posts: 215

    Andrew:
    With respect to the owner field, my instructions read: "If this field is all blanks, the record is available for sale."

    So when I am in my synchronized method, I simply check to see if the owner field is all blanks. If it is NOT, the attempt to update the owner is aborted with the appropriate exception, regardless of whatever else is true.

    Shouldn't this alone prevent Client B (in your scenario above) from updating the record with his number?

    Thanks for any help with this..

    P.S. I still intend to use the lock() and unlock() methods..What exactly they are supposed to be used for, is what will be revealed, I am sure, as I progress through the project.

    I imagine that they are supposed to allow the user to lock the records for a period of time (with a blank owner) while s/he is deciding whether or not s/he wants to book them.
    [ February 24, 2006: Message edited by: Bob Nedwor ]

    Bob N
    SCJP - 1.4
    SCJD - (B&S) Used 1.5 And It Runs On Solaris10
    SCWCD - Thanks to HFSJ!!
    Andrew Monkhouse
    author and jackaroo
    Marshal Commander

    Joined: Mar 28, 2003
    Posts: 11481
        
      94

    Hi Bob,

    I assume you are suggesting having Data's update() method check that the owner field is still blank. If my assumption is incorrect, then the rest of my post wont make sense.

    There is nothing about the methods listed in the interface, or about the Data class itself that is specific to the data being accessed. That is, the class and the methods could work with URLyBird's data file, Bodgitt & Scarper's data file, or any other data file you care to think of (for example a customer database). All that is required is that the magic cookie must match, and the meta-data format must match. The data structure can be determined from the meta data, and you can search in any field, and update any field with the methods provided.

    But the moment you configure Data's update() method such that it checks whether the owner field is blank or not, you are restricting the Data class to only being able to process one form of data: the particular data file you are using in your assignment.

    To keep the Data class reusable, you should move the business logic away from the Data class - move it to some class that just handles booking your particular record type.

    You will also find that concurrency should be improved by doing this. If you are synchronizing Data class' update() method and validating availability within it, you are effectively blocking for the entire sequence:
  • read data from file or cache
  • convert data into record
  • confirm record is not deleted
  • confirm record is available
  • add customer details into record
  • convert record into data
  • write data back into file
  • That is a large synchronized block - and no other client can access any other Data method while this is happening . Whereas if you move the business logic out of the Data class, you will find that only steps 1 and 7 need to be synchronized (plus the synchronization for the lock() and unlock() methods, but they can be synchronized on a different object). So concurrency can be much higher.

    Regards, Andrew
    Bob Nedwor
    hangman
    Ranch Hand

    Joined: Aug 17, 2005
    Posts: 215

    Thanks so much, Andrew. I think that I am on board with everything you have said except for one question. When you say:
    But the moment you configure Data's update() method such that it checks whether the owner field is blank or not, you are restricting the Data class to only being able to process one form of data: the particular data file you are using in your assignment.
    , even though it is NOT my Data.updateRecord() method that is directly doing the checking of the owner field, is there some particular verbage in my assignment (instructions.html) that supports this need for flexibility across multiple data formats that I have missed? I've been over these instructions several times and I just don't see this need expressed anywhere. Based on everything I see, it seems that I am free to assume that my Data class (and the object/methods that are indirectly called) ONLY needs to work with the form of the data in the file that was given me when I downloaded the project.

    I am really scared that I have missed something important here, so thanks for any further explanation.

    In general practice, yes, I see how making the Data class, and all of its resulting functionality, flexible enough to handle a variety data formats is preferrable, but I can't see how this is particularly relevant in this assignment.
    [ February 25, 2006: Message edited by: Bob Nedwor ]
    Andrew Monkhouse
    author and jackaroo
    Marshal Commander

    Joined: Mar 28, 2003
    Posts: 11481
        
      94

    Hi Bob,
    is there some particular verbage in my assignment (instructions.html) that supports this need for flexibility across multiple data formats that I have missed?
    No, there isn't. However there are 30 points available for OO design. Combine that with my earlier comment about nothing in Data class being specific to the data you are actually working with, and I think there is a very good case for making Data class reusable.

    Regards, Andrew
    Bob Nedwor
    hangman
    Ranch Hand

    Joined: Aug 17, 2005
    Posts: 215

    Ok, then you guys win. :roll: I will go ahead and build some code that reads in the 54-character header, parses it out, and programatically determines the number of fields and their lengths, etc, rather than just assume that the "name" will always be 32, the location will be 64, etc. (which then brings up the question: "if this is what they truly expect, then why to they tell us the fields and their respective lengths in the instructions anyway?? )

    I guess having been in QA so long, dealing with so many cheezy developers trying to take the easy way out, I have picked some of their bad habits.
    Ed Tse
    Ranch Hand

    Joined: Sep 18, 2003
    Posts: 183
    Andrew, when you say make Data object reusable, does it mean that I can still implement the data file format according to the requirement of the assignment? As long as I implement it in a way without looking at the schema of the sample DB file, this database object is reusable, right?


    SCJP, Pre-SCJD (URLyBird 1.3.1), Teradata Cert'd Prof
    Bob Nedwor
    hangman
    Ranch Hand

    Joined: Aug 17, 2005
    Posts: 215

    Edward,
    I think what Andrew is trying to say is that our project should not entirely depend on the "name" field being 32 chars, the "location" field being 64 chars, etc, even though they tell us this. Our Data.class needs to be flexible to handle different fields, field lengths, etc in the interest of a truly OO design. He didn't directly tell me I would fail if I didn't proceed in this fashion, but I suspect it would hurt my chances tremendously. See his comments above.

    I just finished spending a whole bunch of time re-doing everything I have done so far so that my project programmatically parses out the header file, determines the schema and builds the Data.class from there.

    Now everything that I have done so far will still work on a different data file, if they decide to change the width of a field, the number of fields, etc.

    I hope this makes sense. Sorry to hear you got stuck with the URL bird project. Let me know if you need any help on some of the commonalities, but I am still trying to figure out B&S.
    [ February 26, 2006: Message edited by: Bob Nedwor ]
    Ed Tse
    Ranch Hand

    Joined: Sep 18, 2003
    Posts: 183
    Thanks, actually I am not stuck, I have just bought the exam last monday and didn't get the exam till last Wednesday. I spent a night on reading the requirement and coding Data.java. All the required methods are almost done. I guess I will start the business logic and put synchronize the stuffs that need to be atomic.
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: synchronized methods vs locking (e.g. update)