从本地机器上的多个线程通过 RMI 调用线程安全方法是否安全?

Is it safe to call a thread safe method through RMI from multiple threads on the local machine?

我有一些方法将通过 RMI 调用远程方法,如下所示:

/**
 * 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());
    }
}

如果远程方法是线程安全的,多线程调用someMethodAccessedByMultipleThreads是否安全?

还是有一些RMI-threading/networking/something_else问题?

即使 RMI 尝试过,它也无法破坏这里的东西。

你看,端点,调用的方法存在于单个 JVM 中。这是一个单一的方法。如果您以线程安全的方式实现了该方法,那么您就很好;否则你不是。

从那里开始:当 JVM 调用该方法时; who/what 触发调用有关系吗?

换句话说:线程安全是本地 属性。不管 "client" 机器上发生了什么;以及如何实现将 "invocation" 请求传输到 "remote server" 机器的协议;到底;您正在处理单个 JVM,只有一个 "method endpoint"。

如果那个东西实施得当,事情就会成功;否则它们会破裂;无论调用该方法的 n 个线程是从 "inside the remote server" 还是从其他系统上的其他线程获得命令。

要真正说明这一点:有责任确保您对该待 RMI 方法的实现是线程安全的。如果你搞砸了,那么肯定会出问题。但是当你有多个线程调用非线程安全的非 RMI 方法时也是如此。

如果我理解正确的话,你问的是客户端生成的 RMI stub 实现是否线程安全。

我确定它们是线程安全的,但似乎没有任何地方记录。我在 RMI 规范中找不到任何明确提到存根是或不是线程安全的。如果某些内容不是线程安全的,通常 会记录下来。

在这个关于 Thread safety of RMI stubs 的论坛问题中,有人提到 RMI 存根是无状态的,因此是线程安全的。问这个问题的人也在 Java 6 中进行了一些测试,证实了存根的线程安全性,但他也提醒说,由于它不在规范中,它可能会在未来的版本中发生变化(尽管这是我认为不太可能)。

很难准确地辨别你在说什么,但我会做两个声明。

  1. 远程 存根 是线程安全的。很多年前,我在 [已失效的] RMI 邮件列表上问过这个问题,答案刻在 Bob Scheifler、Ann Wolrath、Peter Jones 或其他作者之一的石碑上,不仅针对 RMI,而且针对整个JDK:它是线程安全的,除非 Javadoc 另有说明。

  2. 远程方法实现不是线程安全的。这个断言的来源是远程方法调用规范中的 gnomic 语句,大意是 RMI 不保证客户端线程和服务器端线程之间的任何关联。这其中的神秘含义是您不能假设 RMI 在服务器上是单线程的

要得出的结论是,如果您的远程方法实现是线程安全的,那么从任何客户端中的多个线程或同时从多个客户端调用它也是如此,这相当于从 RMI 的角度来看也是一样的。