• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

stuck by lock

 
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
my assignment is FlightByNight. now i am stuck by lock() and unlock().
my idea about it is:
technically, for each request to Data, both local and remote, a new data object should be return to the client.
for multithread request, each thread will get a new instance of the Data. when a thread try to write a record, how it can let others know that the recorde is locked.
would you pls. advice me?
Regards,
Paul
[ June 24, 2003: Message edited by: Paul W Lee ]
 
author and jackaroo
Posts: 12200
280
Mac IntelliJ IDE Firefox Browser Oracle C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Paul
Welcome to JavaRanch.
Are you asking whether your concept will work? Or are you asking for alternatives?
Regards, Andrew
 
Paul W Lee
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
if the concept not correct, then alternatives.
thanks!
[ June 21, 2003: Message edited by: Paul W Lee ]
 
ranger
Posts: 17347
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Paul. I would say that your concept won't work. Here is why. You state that each client will have its own instance of the Data object. It also sounds like you are going to implement locking in local mode.
First if you implement locking in local mode. Since you are the only client there is no need to have locking. This becomes a redundancy.
In remote there should be one instance of the Data class that all the clients have a reference to. This point could be a big reason why you are stuck right now.
Also do a search on LockManager to find out about designing a LockManager class to handle all the clients locks on behalf of the Data class.
Good Luck.
Mark
 
Paul W Lee
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Mark,
it is exactly the reason why i am stuck.
/////////////////////////////////////////
at the beginnig, i had the idea that all the clients has a same instance of Data class. however, i thought since the Data.write() is a synchronized method, wont it be that only one client can get write() method and others have to wait()? so i think each client should have its own instance of Data.
in order to implement this idea, i set the lock as a static variable of class Data so that every instance has the same variable to determine whether a recorder is availbe.
////////////////////////////////////////
if like what you said, that all clients have a same instance, is it correct to say that the write() must not be synchronized so that all/some clients can use it at the same time?
thanks.
[ June 21, 2003: Message edited by: Paul W Lee ]
 
Andrew Monkhouse
author and jackaroo
Posts: 12200
280
Mac IntelliJ IDE Firefox Browser Oracle C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Paul
I think you will find it easier to have one instance of the Data class. If you have more than one, you will have problems with the add method.
I don't see a problem with the modify method being synchronized. The amount of data being written is very small, so you are unlikely that other clients will be waiting for long. Plus, being synchronized means that the JVM will ensure that calls to the seek() and the writeRecord() methods will be treated as an atomic block, which is desirable.
Regards, Andrew
 
Mark Spritzler
ranger
Posts: 17347
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What Andrew said.
Mark
 
Paul W Lee
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
i'd like first ask for advice about synchronized.
"I don't see a problem with the modify method being synchronized. The amount of data being written is very small, so you are unlikely that other clients will be waiting for long. Plus, being synchronized means that the JVM will ensure that calls to the seek() and the writeRecord() methods will be treated as an atomic block, which is desirable."
====>Paul
if modify() is synchronized and Data class has only one instance for all clients, wont it be like below:
for all clents who want to write, even to different recorders, only one client can write at one time.
wont the perfomance be too slow?
Also, if synchronized modify() and only one instance of Data class, since modify() is already synchronized, and only one client can get this mehtod as an atomic block at one time, it seems it's not necessary to implement lock/unlock at all. it has already been thread safe, dosent it?
========================

"I think you will find it easier to have one instance of the Data class. If you have more than one, you will have problems with the add method."
========>
the client adding a new record needs to get database lock, and the other clients will wait() for it. is there any possible problems?
====================

thank you for you kindness, Andrew and Mark.

Paul
 
Andrew Monkhouse
author and jackaroo
Posts: 12200
280
Mac IntelliJ IDE Firefox Browser Oracle C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Paul

if modify() is synchronized and Data class has only one instance for all clients, wont it be like below:
for all clents who want to write, even to different recorders, only one client can write at one time.
wont the perfomance be too slow?


modify() is a very simple method. It does a check to ensure that you are not going to create a duplicate record, then writes the data to disk. You really want that all done atomically - if you are unsure why, please ask.
You would only gain a slight increase in speed if you took the duplication check out of the synchronized block, but if you did that, then you could no longer guarantee that the duplication check would work. If perfomance was an issue, then the check for duplicates could be handled differently (perhaps by storing indexes in memory, or in a separate file), but performance is not a factor for this assignment.
It does sound like you are confusing how the modify() method is to be used. Particularly it sounds like you think that the modify method may be blocking while waiting for user input, but this is not the case - each client only calls the modify method when it has the data ready to be written. So the check for duplicates and write of data should be completed very quickly.

Also, if synchronized modify() and only one instance of Data class, since modify() is already synchronized, and only one client can get this mehtod as an atomic block at one time, it seems it's not necessary to implement lock/unlock at all. it has already been thread safe, dosent it?


Someone here has argued before that the lock and unlock methods are complete as they are. They then recommended that a lock manager be created externally to the Data class to manage record locking and track ownership of the locks.
People do pass using lock managers, and they do pass tracking record locking within the Data class, so whichever method you feel comfortable with should be OK.
But some form of locking is necessary. If two clients do a query which returns one seat available for a given flight, and both try and book it, you need some way of telling one of the clients that their update failed. To do this, you really need a lock mechanism somewhere.

Andrew: "I think you will find it easier to have one instance of the Data class. If you have more than one, you will have problems with the add method."
Paul: the client adding a new record needs to get database lock, and the other clients will wait() for it. is there any possible problems?


Personally I don't like locking the entire database just to create a new record, however I do acknowledge that it may be easier to code than my solution.
The problems with the create method and having multiple Data classes is:
  • how do you ensure that all other instances of the Data class agree with the number of records in the database?
  • how do you ensure that only one instance of the Data class is calling the create() method at any given time?
    The second issue is handled by the fact that you are locking the entire database. The first can also be handled simply. (To be honest, I did have multuple instances of Data class in my submission, and I handled these issues, but I wish I hadnt gone with the multuple instances of Data class). However, the instructions do state that the provided classes are complete with the exception of three methods, so I dont think we should be modifying the Data class.
    Regards, Andrew
  •  
    Paul W Lee
    Ranch Hand
    Posts: 40
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Andrew,
    Thank you for your details.
    briefly, you think that the basic reason why lock/unlock are needed is that when 2 clients try to update the same recorder, but the 1st one update the seat nubmer to 0, the 2nd one should be notified that the number is 0. and generally, you agree with my opinion that single instance with synchronized modify()/write() IS thread safe.
    is it right?
    Paul
     
    Andrew Monkhouse
    author and jackaroo
    Posts: 12200
    280
    Mac IntelliJ IDE Firefox Browser Oracle C++ Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi Paul,
    Basically I agree with your statements, but I am going to clarify them (because I am really pedantic )

    you think that the basic reason why lock/unlock are needed is that when 2 clients try to update the same recorder, but the 1st one update the seat nubmer to 0, the 2nd one should be notified that the number is 0


    I agree, except for "the 2nd one should be notified that the number is 0". The instructions tell us that live updates are not required.
    What should be happening is that when the second client attempts to book 'x' seats, then they should get an exception stating that the requested number of seats were not available.
    Just a minor change to your statement.
    Regards, Andrew
    [ June 22, 2003: Message edited by: Andrew Monkhouse ]
     
    Paul W Lee
    Ranch Hand
    Posts: 40
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Andrew,
    you're really helpful.now i am got clarified, and believe that your logic about single instance is reasonable.
    just because of technical interest, i want to know more about lock of mulit instance . if multi instances are created, like your submission was, how to control two different instances writing the same recorder.
    at first, my idea was to use a static lock variable in the Data class. unfortunately, it seems that dose not work because the wait() object can not be notified by using the static lock.would you agree with this?
    is the correct way to use trace the client id, for example, putting the current thread name into a data structure in the lockManager() class?
    Thanks a lots.
    Paul
    [ June 22, 2003: Message edited by: Paul W Lee ]
     
    Andrew Monkhouse
    author and jackaroo
    Posts: 12200
    280
    Mac IntelliJ IDE Firefox Browser Oracle C++ Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi Paul,

    at first, my idea was to use a static lock variable in the Data class. unfortunately, it seems that dose not work because the wait() object can not be notified by using the static lock.would you agree with this?


    Every object has a lock (or monitor) associated with it. This is true even for static objects.
    In my case, I had a static HashSet that held the record numbers that were locked, and synchronized on that set.

    is the correct way to use trace the client id, for example, putting the current thread name into a data structure in the lockManager() class?


    If you are using sockets, then this should be OK.
    But if you are using RMI, then you are not guaranteed that the call to lock(), modify(), and unlock(), will all operate in the same thread.
    So the answer depends a bit on the protocol you are using.
    I'll leave you to think about that for a little while before giving you any hints.
    Regards, Andrew
     
    Paul W Lee
    Ranch Hand
    Posts: 40
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Andrew,
    i'd like to know more about multi instance issues.
    for multi instances application, a static lock( hashset in your submission) is needed. now i am wondering whether all instances of the class will be blocked until the instance(client) that requests the lock releases the lock.
    for instance, let's imagine the situation below:
    there are two clients, client1 and client 2. client1 gets an instance of the data class and is gonna to write the recorder 1, while client 2 gets another instance to write recorder 2. client1 first gets the lock( your hashest). when it is writing the new data into recorder 1, is the client2, who is trying to write new data into recorder2, able to get the lock to write recorder2?
    if yes, would you teach me the reason. if not, it seems that there is no difference btw multi instances from single instance, because all writing jobs have to be in a squence, but not concurrently.
    regards,
    Paul
    [ June 23, 2003: Message edited by: Paul W Lee ]
     
    Andrew Monkhouse
    author and jackaroo
    Posts: 12200
    280
    Mac IntelliJ IDE Firefox Browser Oracle C++ Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi Paul,
    There are three distinct steps here. They are:
  • lock
  • modify (could be create, update, or delete)
  • unlock

  • The lock method synchronizes on an object (in my case a HashSet) to ensure that only one instance of the lock can be getting a lock at any given time. But the synchronization is not the granting of the lock.
    Perhaps it might help to think about a real world equivalent: several people all going to the one clerk and asking for locks. Since the clerk can only deal with one person at a time, you cannot have two people asking for the same lock simultaneously. If the lock has not already been granted, the clerk approves the request and writes down somewhere which locks have been granted. If the lock has already been granted, the clerk tells the requesting person to wait. Those people who have had their requests granted can go off and work.
    So the synchronization on the object is the equivalent of having a single clerk to process requests.
    You still have to have somewhere for the clerk to keep track of which requests have been granted. Hopefully it should be obvious what they can be stored in.
    With this, the following scenario could occur:
  • client A locks record 5
  • client B locks record 7
  • client A modifies record 5
  • client B modifies record 7
  • client B unlocks record 7
  • client A unlocks record 5


  • It is not as though client B would have to wait until client A has completed the entire lock-modify-unlock procedure before it could do any work.
    As you can see in my example above, it is even possible (say due to network issues) that client B could complete before client A has completed.
    Regards, Andrew
    [ June 24, 2003: Message edited by: Andrew Monkhouse ]
     
    Paul W Lee
    Ranch Hand
    Posts: 40
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Andrew,

    your story is helpful, and it helps me figure out how to implement a static lock.

    Originally posted by Andrew Monkhouse:
    Perhaps it might help to think about a real world equivalent: several people all going to the one clerk and asking for locks. Since the clerk can only deal with one person at a time, you cannot have two people asking for the same lock simultaneously. If the lock has not already been granted, the clerk approves the request and writes down somewhere which locks have been granted. If the lock has already been granted, the clerk tells the requesting person to wait. Those people who have had their requests granted can go off and work.


    now i implement a LockManager class, and a DataServer Class. they are like:
    LockManager(){
    // for simple implementation, i use an array
    static Array[] locks;
    synchronized lock( int recNo );
    synchronized unlokc( int recNo );
    }
    DataServer(){
    static Lock aLock;
    synchronized write( Data aData, int recNo );
    }
    Data(){
    //no change to the orignal version
    }
    it seems to work as the same sequence as what you described.
    but one thing that makes me confused is why i can not put the static Lock into the Data class. when i tried to do that, the wait() thread can not be notified.
    would you give me some ideas about this situation?
    thank a lots.

    Paul
    [ June 24, 2003: Message edited by: Paul W Lee ]
     
    Andrew Monkhouse
    author and jackaroo
    Posts: 12200
    280
    Mac IntelliJ IDE Firefox Browser Oracle C++ Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi Paul
    I don't understand why you can't have the static lock in the Data class either. As far as I can tell, it should work.
    When you say that the wait() thread cannot be notified - what happens? Do you get an exception? Or does it appear to work but nothing happen?
    Regards, Andrew
     
    Paul W Lee
    Ranch Hand
    Posts: 40
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Andrew Monkhouse:
    Hi Paul
    I don't understand why you can't have the static lock in the Data class either. As far as I can tell, it should work.
    When you say that the wait() thread cannot be notified - what happens? Do you get an exception? Or does it appear to work but nothing happen?
    Regards, Andrew


    i tried that again, now it woks by puting the lock in Data class.
    thanks Andrew, i have done this for more than one week.
    Another question( if you dont feel to be botherd too much):
    why it needs to be recorded that which client is controlling the lock for a specific recorder? since each recorder can be modified/writed by only one client at one moment, isnot it enough?
    thanks.
    Paul
     
    Andrew Monkhouse
    author and jackaroo
    Posts: 12200
    280
    Mac IntelliJ IDE Firefox Browser Oracle C++ Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi Paul
    Tracking which client owns the lock is one way to meet the requirement If an attempt is made to unlock a record that has not been locked by this connection, then no action is be taken. It is not the only way to meet that requirement, so you might not have to track client IDs.
    Regards, Andrew
     
    Paul W Lee
    Ranch Hand
    Posts: 40
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Andrew,
    Thank you so much.
    Paul
     
    Paul W Lee
    Ranch Hand
    Posts: 40
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Andrew Monkhouse:

    Personally I don't like locking the entire database just to create a new record, however I do acknowledge that it may be easier to code than my solution.
    The problems with the create method and having multiple Data classes is:

  • how do you ensure that all other instances of the Data class agree with the number of records in the database?
  • how do you ensure that only one instance of the Data class is calling the create() method at any given time?
    The second issue is handled by the fact that you are locking the entire database. The first can also be handled simply. (To be honest, I did have multuple instances of Data class in my submission, and I handled these issues, but I wish I hadnt gone with the multuple instances of Data class). However, the instructions do state that the provided classes are complete with the exception of three methods, so I dont think we should be modifying the Data class.


  • Andrew,
    i have just implemented a LockManager, and for all requests there is only a single instance of Data class which uses the LockManager.
    now when i review the project, again i have some quesions about the multi instances of Data class.
    you said, "how do you ensure that only one instance of the Data class is calling the create() method at any given time?"
    i am thinking when an creat() is invoked, the whole database is locked by the thread that wants to create new recorder. then this thread dose not create the new recorder until it makes sure that no thread is doing job. it means the creating thread waits for all threads that have already existed before it comes. only if all the threads finish their jobs, the create() thread starts to create the new recorder. meanwhile the entire database is locked, so no other threads can enter to create/modify the database.
    will this assumption have any problem?
    Regards,
    Paul
     
    Andrew Monkhouse
    author and jackaroo
    Posts: 12200
    280
    Mac IntelliJ IDE Firefox Browser Oracle C++ Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi Paul

    for all requests there is only a single instance of Data class which uses the LockManager.


    So if there is only a single instance of Data class, then your questions are just out of curiosity?

    Andrew: how do you ensure that only one instance of the Data class is calling the create() method at any given time?


    This question only applies if you have multiple instances of the Data class.
    But, if you did have multiple instances of the Data class, then locking the entire database is one way of ensuring that only one of those instances is ever creating new records at any given time.
    It still leaves the other issue though: how to ensure that all instances of the Data class agree about how many records exist in the database. To fix this, you have to make a change to the Data class. I don't think we should really do this though, since the Sun instructions tell us that the Data class should be considered complete with the exception of the three methods we have to write. So I don't think we should be modifying other fields in the Data class.
    Regards, Andrew
     
    Paul W Lee
    Ranch Hand
    Posts: 40
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    i am going to submit the single instance solution, but i'd like to discuss more about multi instance.

    Originally posted by Andrew Monkhouse:

    It still leaves the other issue though: how to ensure that all instances of the Data class agree about how many records exist in the database. To fix this, you have to make a change to the Data class.


    the only situation for clients that they should know how many recorder exist in the database, i believe, is searching all recorder. then there needs a read lock for the database, or for a specific recorder(the lastest added one).

    is there any other situations for knowing all recorders?
    ===============================================
    Another question's about the single instance. if there is only a single instance, there should be a static server or the server has a static instance of the Data class. for this situation, how to handle requests for different data source( the db.db).

    Paul
    [ July 05, 2003: Message edited by: Paul W Lee ]
     
    reply
      Bookmark Topic Watch Topic
    • New Topic