Win a copy of Think Java: How to Think Like a Computer Scientist this week in the Java in General forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Problem with Synchronized method using RMI

 
Howard Kresin
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a basic data class Customer which has 4 fields, LastName, FirstName, UserID, and TransactionNo

My RMI setup is as follows:

Client takes LastName and FirstName as arguments and gets the UserID and TransactionNo programmatically

The Client looks like the following:
<After connecting to the server>



The ServerImpl can process the data from the Client and looks like:



The problem that I am having is that if I instance two Clients and make each Client instance loop around 1000 time, most of the time I will get what I expect:

Before : Client A�s data
After : Client A�s data

Every so often though, I will see:
Before : Client A�s data
After : Client B�s data

This happened whether I synchronized on the SetGet function or on the customer object. (The code shows it both ways)

More detailed logging of ServerImpl indicates that where the problems appear (I can tell by the TransNo) after entering the synchronized block or function, the block or function is interrupted by the other Client.

Any help would be appreciated.
 
Erik Larson
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It took me a while to recreate your problem, but I finally did. The synchronization is not really the problem. I did tests and I did not see an instance in which two Threads had access to the Server.customer at one time. Where the problem comes in is that you are returning a reference to the Server.customer. This same reference is then locked by the next Thread that tries to access the GetSet method. The problem is that on the client, you use the same reference. Scenario:

1. Client 1 calls GetSet()
2. GetSet() returns with Server.customer reference, values set to Client 1
3. Context switch to Client 2.
4. Client 2 calls GetSet()
5. GetSet() returns with Server.customer reference, values set to Client 2
6. Context switch to Client 1.
7. Client 1 prints customer.toString() with values from Client 2 because customer in Client 1 holds the same reference, but with updated content.

My solution was to make Customer implement Cloneable and return a clone of Customer from getCustomer(). I'll put all my code in here...

Customer.java


Server.java


ServerImple.java


ThreadedCustomer.java


Hope this helps!
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic