1

I have some method which is going to call remote method through RMI as the following:

/**
 * Implementation is supposed to be thread safe
 */
public interface Act extends java.rmi.Remote{
    String doSome() throws RemoteException;
}

public class SomeClass {
    private static final Act stub = (Act) Naming.lookup("/server/stub")

    public static void someMethodAccessedByMultipleThreads(){
        System.out.println(stub.doSome());
    }
}

If the remote method is thread safe is it safe to call someMethodAccessedByMultipleThreads by multiple threads?

Or are there some RMI-threading/networking/something_else issues?

user207421
  • 305,947
  • 44
  • 307
  • 483
St.Antario
  • 26,175
  • 41
  • 130
  • 318
  • This feels like a dupe of [What is meant by “thread-safe” code?](http://stackoverflow.com/questions/261683/what-is-meant-by-thread-safe-code); but I'll hold off on the dupe hammer for now. – Andy Turner Apr 21 '17 at 08:33
  • 1
    @AndyTurner I dont think so. My question is mostly about rmi and how it guarantees thread safety (if so). – St.Antario Apr 21 '17 at 08:34
  • 2
    RMI is just invoking a method on some other machine; from the perspective of that machine, it's not RMI, it's just MI. So, if it's *really* thread safe there, why would calling it in some way - where the call happens to come via an RMI framework - break that thread safety? – Andy Turner Apr 21 '17 at 08:38
  • @AndyTurner I mean two threads call the same remote method simultaneously and expect to receive some result. Maybe there is some networking issue about that so the result received by these threads is corrupted due to collision. – St.Antario Apr 21 '17 at 08:40
  • If it's thread-safe it's thread-safe. Unclear what you're asking. – user207421 Apr 21 '17 at 08:50
  • I have to admit: I like your question. It gives food for thought. – GhostCat Apr 21 '17 at 09:06
  • @EJP Two threads simultaneously invoke the same remote method. In order for to do that the threads need to transfer some commands to the remote machine and receive the result. They use the same port, so threads will receive data from the same port and therefore there might a collision. – St.Antario Apr 21 '17 at 09:29
  • Only if they use the same connection, which they don't. If they did the result would be an unimplementable mess. See my answer. – user207421 Apr 21 '17 at 09:34
  • @EJP - the question is about a thread-safe _remote method_ being called from multiple threads over RMI. Clearly there should be no issue with the remote method itself, but as I understand it the concern is that, for example, the local stub may not be thread-safe, or the remote receiving framework may not be able to handle concurrent calls from the same stub (which is really another way the local stub could be not-thread-safe). – BeeOnRope May 17 '17 at 22:41

3 Answers3

4

Hard to discern exactly what you're talking about, but I will make two statements.

  1. Remote stubs are thread-safe. I asked this question many years ago on the [defunct] RMI mailing list, and the answer came forth engraved in stone tablets from Bob Scheifler, Ann Wolrath, Peter Jones, or one of the other authors, not just for RMI but for the entire JDK: it's thread-safe unless the Javadoc says otherwise.

  2. Remote method implementations are not thread-safe. The source for this assertion is the gnomic utterance in the Remote Method Invocation Specification to the effect that RMI makes no guarantees about any association between client-side threads and server-side threads. The occult meaning of this is that you cannot assume RMI is single-threaded at the server.

The conclusion to be drawn is that if your remote method implementation is thread-safe, so is calling it from multiple threads in any client, or multiple clients simultaneously, which amounts to the same thing from RMI's point of view.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Huh, your point (1) is very interesting. It seems like a wrong approach given that the vast majority of JDK classes are not thread safe, so you have to document nearly every class and if you forget the default is "unsafe" (i.e., based on the guarantee, if you forgot to document a class users may assume it is thread-safe, rather than the other way around). Still, I clicked through a dozen Java docs and indeed every one which I knew not to be thread-safe contained a disclaimer to this effect. So maybe they are actually doing this... – BeeOnRope May 17 '17 at 22:46
  • @BeeOnRope The statement applies to the JDK. What you do with your own classes is up to you. – user207421 Apr 18 '20 at 06:12
2

Even when RMI tried, it couldn't break things here.

You see, the endpoint, the method that is invoked exists within a single JVM. It is a single method. If you implemented that method in a thread-safe manner, then you are good; otherwise you are not.

And from there: when that JVM invokes that method; does it matter who/what triggers the invocation?

In other words: thread-safety is a local property. No matter what happens on the "client" machine; and how the protocol is implemented that transports the "invocation" request to the "remote server" machine; in the end; you are dealing with a single JVM, with a single "method endpoint".

If that thing is implemented correctly, things will work; otherwise they will break; no matter whether the n threads calling that method got their orders from "inside the remote server" or from some other thread on some other system.

To make that really clear: it is your responsibility to make sure that your implementation of that to-be-RMI'ed method is thread safe. If you mess up, then sure, things will go wrong. But the same is true when you have multiple threads calling a non-RMI method that is not thread-safe.

user207421
  • 305,947
  • 44
  • 307
  • 483
GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • 1
    RMI method implementations are only thread-safe if the implementor makes them so. It isn't inherent in RMI. – user207421 Apr 21 '17 at 08:53
  • The paragraph that needs fixing is the second one where you blindly assert that the method impllementation is thread-safe.. – user207421 Apr 21 '17 at 09:28
  • 1
    I see. Better now? – GhostCat Apr 21 '17 at 09:31
  • Not really. The claim seems to be that everything happens on a single machine (the remote machine?), so it's safe but of course there are all the mechanics of issuing the RMI call in the first place. Certainly it is not some kind of obvious standard that [stubs are threadsafe](http://stackoverflow.com/questions/1950080/are-axis2-generated-stubs-thread-safe) - and making it so involves some implementation effort (whatever state machines, sockets, etc are inside the stub need to handle multiple concurrent calls, etc). – BeeOnRope May 17 '17 at 22:49
1

If I understand the question correctly, you asking if the client's generated RMI stub implementations are thread-safe.

I'm sure they are implemented thread-safe but it doesn't seems documented anywhere. I can't find any explicit mentioning of stubs being or not being thread safe in the RMI spec. It usually is documented if something is not thread-safe.

In this forum question about Thread safety of RMI stubs someone mentions RMI stubs being stateless and therefore thread-safe. The person who asked this also ran some test in Java 6 which confirmed the thread-safety of stubs, but he also reminds that since it's not in the spec it may change in future versions (though this is unlikely in my opinion).

kapex
  • 28,903
  • 6
  • 107
  • 121
  • Your link is about Spring Remoting, not Java RMI. Java RMI stubs are thread-safe, by virtue of the Javadoc not stating otherwise. – user207421 Apr 21 '17 at 08:51
  • @EJP The linked thread is mostly about Java RMI, there doesn't seem to be many Spring Remoting specific things mentioned (except maybe that it's used to create remote objects). – kapex Apr 21 '17 at 09:03
  • The linked thread was posted on a Spring forum, and it is about a remote proxy obtained rom `RmiProxyFactoryBean`, which is a Spring class. – user207421 May 17 '17 at 22:21
  • @EJP yes, as I said Spring is mentioned to be used to get the remote proxy. `RmiProxyFactoryBean` obtains it via the RMI registry though, just like you would do without Spring. Just because it's posted in a Spring forum doesn't make their observations about RMI stubs invalid. I doesn't look like Spring is providing it's own proxy implementation nor does it seem to be interfering with stub methods invocations in any way. – kapex May 18 '17 at 09:19