This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
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 ]
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
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
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.
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
Joined: Apr 24, 2003
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