wood burning stoves 2.0*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Please Help --  Question on testing lock() with multiple threads 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 "Please Help --  Question on testing lock() with multiple threads" Watch "Please Help --  Question on testing lock() with multiple threads" New topic
Author

Please Help -- Question on testing lock() with multiple threads

Meena Pitchiah
Greenhorn

Joined: Apr 24, 2003
Posts: 16
Hi,
I am testing lock() with multiple clients. My test program spawns multiple threads and tries to book the same flight
concurrently. I see some strange behaviour
Created 3 threads. Each thread tries to book one ticket for the same flight. First two threads succeed in booking and
unreferenced() gets called for those two RemoteData objects. Third one is waiting to acquire the lock. After that I have
no idea what happens to that remote object which is waiting for the lock. If some delay is introduced between creation
of threads it works perfect. All the threads succeed. Is it OK to introduce delay like this for testing. Can someone
please help review my lock and unlock methods.

Here is my lock and unlock methods of RemoteData class. Using HashMap for locking.

thanks
Meena
[Andrew: Added [code] blocks to make this more readable]
[ September 04, 2003: Message edited by: Andrew Monkhouse ]
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11404
    
  81

Hi Meena,
As you may notice, I have put your code inside a [code] block which ensures that indentation is kept. This makes your code more readable, which may help you to get more comments - there are some people who will not read code that is not formatted. If you edit your post above, you should be able to see the start and end code block statements. Also you can look at the UBB code description page.
Now as to your problem ....
I noticed that you are using the 'this' reference to track ownership of the lock. This implies you have one instance of the Data class per connected client. If I am wrong then the remainder of these comments do not apply.
If you have one instance of Data class per connected client, then synchronizing the lock and unlock methods does nothing for you. They are only synchronized within the thread itself, not against other threads.
Therefore if two threads try and lock the same record simultaneously, they will be in separate instances of the Data class, and so will not block each other. Therefore they could both determine that the record is not currently locked, so both lock their own record. Coincedentally they will both appear to have worked (although not really - they updated concurrently, not one after the other).
Meanwhile the third client came in moments later and determined that the record was locked. So it goes into wait() state, waiting until this thread notifies it that it can wake up. Does something in what I just said strike you as incorrect
Regards, Andrew


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

Joined: Apr 24, 2003
Posts: 16
Hi Andrew,
Thanks for the information about the UBB Code.
I noticed that you are using the 'this' reference to track ownership of the lock. This implies you have one instance of the Data class per connected client. If I am wrong then the remainder of these comments do not apply.

I have one instance of RemoteData per client. But all these RemoteData instances refer to the same instance of Data and HashMap (used for locking / unlocking). I have given is my server design below. Can you please comment on this. You see any problem with this design which causes the original problem?
Server Design :
  • I have an interface called DataInterface. My DataAdapter class implements DataInterface and contains an instance of Data object as a private member. Using Adapter pattern to satisfy the requirement "the implementation should include a class that implements the same public methods as the Data class..."
  • Using RMI for networking. RemoteDataInterface implements DataInterface and Remote. RemoteData class implements remote interface. RemoteData contains two private members

  • private DataAdapter adaptee;
    private HashMap lockMap;
  • Using factory pattern to create a RemoteData object for each client. The ConnectionFactory creates one instance of DataAdapter and HashMap. When the ConnectionFactory class creates RemoteData instance it passes the same instance of DataAdapter and HashMap. So all the RemoteData instances refers to the same DataAdapter (and Data indirectly) and HashMap.
  • Implemented unreferenced() in RemoteData.

  • Thanks,
    Meena
    [ September 04, 2003: Message edited by: Meena Pitchiah ]
    Andrew Monkhouse
    author and jackaroo
    Marshal Commander

    Joined: Mar 28, 2003
    Posts: 11404
        
      81

    Hi Meena,
    I don't think the problem you mentioned is in the locking / unlocking code. I ran the following test, and it all worked perfectly.

    Note that if you uncomment the commented out sections, all threads will attempt to obtain the lock as close to the same time as the JVM will allow. With those lines commented out, then each thread will attempt to gain the lock as the thread is created.
    So in all probability the problem is with either your test case or with your RMI implementation.
    My instinctive feeling is that this may be a problem with how quickly you can make connections to Sun's RMI Registry. If you search in this forum for "java.rmi.ConnectionException" you will see several posts where people found that they could not make too many connections to Sun's RMI Registry in a short time frame.
    In your test case, are you printing all exceptions to screen? Or are you swallowing the exceptions?
    Changing topic: as I mentioned before, I had thought you had one instance of Data class for each connected client because you are using the "this" instance of the Data class to uniquely identify the client. Since you only have one instance of the Data class, your check within the unlock() method will not work.
    Regards, Andrew
    Meena Pitchiah
    Greenhorn

    Joined: Apr 24, 2003
    Posts: 16
    Hi Andrew,
    Thank you for your help.
    I got rid of this problem by changing the lock(), unlock() methods. Initially I was using synchronized methods. I changed to synchronized blocks and synchronized on the HashMap. Now I am able create threads withot any delay between stating the threads. I still don't know why my synchronized method did not work? Have to spend time on this.
    Thanks
    Meena
     
     
    subject: Please Help -- Question on testing lock() with multiple threads
     
    Similar Threads
    Need your help -- IllegalMonitorStateException
    synchronized lock/unlock -> deadlock?
    A client can lock many records at a moment?
    Lock/Unlock Implementation Review
    need lock() be synchronized?