i have two clients in two different processes that communicate through RMI with the server.
my question is:
what happends if both clients invoking the server's stub at the same time?
thanks for you time,
me
This tutorial demonstrates the threaded nature of RMI servers (see task 7.1). They quote from the RMI spec:
A method dispatched by the RMI runtime
to a remote object implementation (a
server) may or may not execute in a
separate thread. Calls originating
from different clients Virtual
Machines will execute in different
threads. From the same client machine
it is not guaranteed that each method
will run in a separate thread
so invocations from different clients will result in execution via different threads in the server.
Nothing untoward by default - it's exactly the same as invoking a method on any other object from two threads simultaneously. The 1 server to many clients model is what network protocols like RMI are for.
Access to any shared data within the server needs to be regulated by synchronized blocks if need be. It depends what the server is doing.
Related
I'm developing a standard java RMI server with multiple clients. These clients have a menu where they can call the server to do various of things for them.
One method involves a queue, where they can send a job to the queue and wait for it to get handled. The RMI server dispose threads for all the clients automatic, but when it comes to this method and queue, how can I hold this request back, so for example:
client 1 call first, and then client 2 calls just after (here client 1 should receive the message first from the server and client 2 should wait the time it takes for the server to process client 1 request)
Is it to make some kind of singleton only for this task?
What can I do to tackle this problem.
Make the remote method concerned synchronized.
No queue required.
We currently have a server that is creating a new thread for each request he gets, so basically the server gets data that he needs to save later.
Now we got the request to implement RMI where we can observe what kind of data is currently being saved.
How can I handle this the best way? Shall I make an RMI Server for each thread? Can I have multiple instances of the same service on the same address and let my observer register to all of them?
I'm using the google example for the RMI access:
https://sites.google.com/site/jamespandavan/Home/java/sample-remote-observer-based-on-rmi#TOC-Running-the-server-client
You don't need a remote object per thread, because you won't even have visible threads. A remote object is already multi-threaded and already takes care of its own incoming connections. You will be throwing stuff away rather than adding.
You might need a remote object per client, if you wamt them to behave like sessions, but that's a different story.
Suppose I have an RMI Client-Server application. Clients connect to the Server and at some point the Server starts a task. During the task Clients are doing some work, but at some other moment the Server must interrupt this work without letting the Clients finish it. Clients are implemented as Threads and the simplest solution looks like calling thread.interrupt(), but this does not work in RMI. Is there any other method or some workaround to resolve this problem? Thanks in advance.
You can implement a two-way remoting scheme in which, when a client performs the lookup for the server remote object and creates the local instance, it calls a method by which it passes a remote object of its own to the server. Then, when the server has finished its task, it can notify the client by calling a method in the remote object received from the client.
Assume that processes in a distributed application are using RMI for interactions between
each other. How can deadlock occur? How to avoid it?
You can get a deadlock via RMI in a system that doesn't deadlock without RMI if you use callbacks. A local callback is executed on the calling thread; however an RMI callback is executed on a different thread from the original client calling thread. So if there is client-side synchronization, a deadlock can occur that wouldn't occur if the calls were all local.
In the local JVM case, the JVM can tell that the calling object "A" owns the lock and will allow the call back to "A" to proceed. In the distributed case, no such determination can be made, so the result is deadlock. Distributed objects behave differently than local objects. If you simply reuse a local implementation without handling locking and failure, you will probably get unpredictable results. Since remote method invocation on the same remote object may execute concurrently, a remote object implementation needs to make sure its implementation is thread-safe. For example when one client logs on to the server in order to maintain security and to avoid deadlock the same customer will not be allowed to logon to the server from another machine. This is done by creating Session Flag.
When i try to run 2 wget commands simultaneously to my server (http://myserver), looks like tomcat allocates two threads to process them. But i believe when tomcat receives two simultaneously from same ip address, it will not create a new thread for processing the second request as it considers both the requests come from same session.
If i want to check if both the threads are same or different, is using thread.getId() the only way? I think this id may be reused for new threads. Is there any unique property of the thread existing to check its identity other than threadid?
I suggest to never rely on threads to identify their source. There are no Servlet spec guarantees about threads, and newer Servlet spec implementations make use of NIO. You are skating on a thin ice.
Web servers will almost always assign multiple threads (or processes) to multiple simultaneous requests, since the client can work faster when it does not have to wait for each response.
Newer servers may use asynchronous IO (nio), however, and a single thread can simultaneously serve many clients.
Yes, Thread.getId() is a way of identifying threads.
Session IDs are the mechanism used to identify requests from a single client.
The IP address is not a good way to do that, since multiple machines can expose the same IP when hiding behind a NAT.
I believe Tomcat will always create a new thread of execution irrespective of whether it comes from the same IP or not. In case, the client application running on the particular IP has a mechanism to send across the session-id, then Tomcat will simply associate the same session context with the request thread [making it stateful].
in your case, you'll need to customise wget to hold on to the session-id [the Tomcat web-app might send it across through a cookie or as a url parameter - jsessionid]. wget will then need to send it back with the subsequent requests [url rewrite and include the jsessionid parameter, or exchange cookies]. this way Tomcat will be able to treat each request coming from a unique client instance and associate a state with it.