• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

NX: RMI and thread safe

 
Rick Lu
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
Now, I am a little confused about RMI and the locking mechanism. My design has multiple data (export to clients), one singleton LockManager which uses wait() and notifyAll().
Most of time, the program runs well in RMI and local modes. However, there are one case in which one record can be locked twice in the network scheme. I think this may be due to the fact that RMI only create one thread for multiplex clients, thus this thread can always hold Lockmanger's Monitor and call codes in synchronized mode.

I have no idea how to make sure one thread for each client. This may not be possible? Any possible solution for this one? Really appreciate your help.
Regards.
Rick
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rick, if you do a search on this forum on "Connection" you will find a solution that creates an Object for each client, that will reside on the server side. This creates a one to one relation. Each of these Connection objects holds a reference to the LockManager, so only one client at a time can hold the lock on the LockManager.
Mark
 
Rick Lu
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Mark,
Thanks for your reply.
I think I did't explain it clearly. Actually I used the connection factory to export a new Data Class for each client. But RMI specification said:
A method dispatched by the RMI runtime to a remote object implementation may or may not execute in a separate thread. The RMI runtime makes no guarantees with respect to mapping remote object invocations to threads.

So even multiple Data objects are created, no guarantees that each Data object will executed with one thread. in which case, wait() can be called by the same thread twice or more because wait() and notifyAll() are based on "THREADS" instead of "OBJECTS", right?( When the thread is in wait(), it can execute some other methods, is it ture???) This can cause unexpected system behaviors.
I have wrong understanding on threads??? Or, any suggestion???
Rick
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
"to export a new Data Class for each client"
This tells me that you are not using the Connection factory solution, that you will find in this forum. In that solution there is only one Data class, whose reference is passed to each client's Remote Connection object residing on the server. If you export a new Data class for each client, then there are more than one instance of the Data class, and therefore 0 percent chance of thread safety.
Mark
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
To quote another thread reply

Hello John
Take a look at the following thread:
Rmi question
http://www.coderanch.com/t/184332/java-developer-SCJD/certification/Rmi
Andrew has done a wonderful job of explaining the Connection Factory concept in the most basic terms.
Enjoy.
Regards.
Bharat

Mark
 
Rick Lu
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In Max's book, he only had one Data instance for all clients. But in my current implementation, I create a new Data instance for each client. However, LockManager is a static (singleton) member in the Data class. Following is my connection factory, there are two classes that extends UnicastRemoteObject: DataRemoteImpl and ConnectionFactoryImpl.
The reason I create multiple Data instance is that there are too much computation workloads in it. So multiple instances can be more efficient.

DBClient is the interface that looks like DBMain but with one extra method "getMetaData().
Is this the right way to implement Connection Factory?
Rick
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Pie
Posts: 12007
215
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Rick,
I think this may be due to the fact that RMI only create one thread for multiplex clients

No. The number of threads that RMI creates is unknown. And which thread will be used to process any given method is undetermined.
You have to use the Sun JDK for this assignment, and so far my testing on Solaris, Linux, Windows 2000, and Windows 95 all shows that multiple threads are used. I would be extremely surprised if Sun released an RMI implementation that only used one thread. However it is technically possible according to the specifications, and any other manufacturer's RMI implementation can do whatever they wish.
However, there are one case in which one record can be locked twice in the network scheme.

I doubt that this would be due to which thread you are using to lock the record. I am more likely to believe that there is some other problem.
I have no idea how to make sure one thread for each client. This may not be possible?

The RMI Specification is explicit that you have no control over which threads are used by RMI. But as mentioned before, I don't think that this is really your problem.
So even multiple Data objects are created, no guarantees that each Data object will executed with one thread. in which case, wait() can be called by the same thread twice or more because wait() and notifyAll() are based on "THREADS" instead of "OBJECTS", right?( When the thread is in wait(), it can execute some other methods, is it ture???) This can cause unexpected system behaviors.

No - when you call wait() it forces the specified thread to wait. That thread should not be used for any other instances.
Is [the code posted] the right way to implement Connection Factory?

Yes, that will get you a connection factory.
Some general questions about your code:
Why do you call super() in your constructors to DataRemoteImpl() and ConnectionFactoryImpl()?
Why do you have a create() method in DataRemoteImpl? Surely it should only be used by the constructor, in which case why not move the logic into the constructor?
Why have you hard coded "localhost" into your hostService string?
Regards, Andrew
 
Rick Lu
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There must be some bugs and problems with my codes. Need to check it out. Now much clear about RMI. Thank you so much Andrew, for your reply and general questions.
Rick
Regards.
 
Rick Lu
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Andrew,
I suppose RMI server only is created on the localhost. Am I right?

Why have you hard coded "localhost" into your hostService string?

We just omit the "localhost" or use IP for it? I don't know whether we need to specify IP address when the server starts. That's beyond the requirement, right?
Rick
Regards.
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Pie
Posts: 12007
215
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Rick,
You can use localhost. Since you are starting the RMI Registry yourself, that is a nice safe option for the server.
The Sun RMI Registry will not allow you to run your service on a machine other than the one where the RMI Registry itself is running. But the specification allows for the two to be on different machines. So in a commercial environment, you might want to have something other than localhost.
Likewise the Sun RMI Registry seems to accept any call on any TCP/IP interface associated with the local host, regardless of what IP address you put in your bind call. But many other servers will only listen on the named IP address. So I would not be surprised if some other registry actually honoured the "localhost" and refused to accept calls from other machines even on the same subnet.
All of which is beyond the requirements. What I meant to ask was whether you used "localhost" on the client side, or whether you allowed the user to specify the IP address.
Regards, Andrew
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic