我有一些方法可以通过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问题?
答案 0 :(得分:3)
很难准确辨别出你所谈论的内容,但我会发表两个声明。
远程存根是线程安全的。多年前我在[已解散的] RMI邮件列表中问过这个问题,答案来自Bob Scheifler,Ann Wolrath,Peter Jones或其他作者之一的石碑,不仅仅是RMI,还有整个JDK:除非Javadoc另有说法,否则它是线程安全的。
远程方法实现 不线程安全。这个断言的来源是远程方法调用规范中的基本话语,即RMI不保证客户端线程和服务器端线程之间的任何关联。这个隐藏的意思是你不能假设RMI是服务器上的单线程。
得出的结论是如果你的远程方法实现是线程安全的,那么从任何客户端的多个线程或同时多个客户端调用它,这相当于RMI的观点。
答案 1 :(得分:2)
即使RMI尝试过,也无法在这里破解。
您看,端点,调用的方法存在于单个JVM中。这是一种方法。如果您以线程安全的方式实现了该方法,那么您就是好的;否则你不是。
从那里开始:当JVM调用该方法时;谁/什么触发调用是否重要?
换句话说:线程安全是本地属性。无论“客户”机器发生什么;以及如何实现将“调用”请求传输到“远程服务器”机器的协议;到底;您正在处理单个JVM,具有单个“方法端点”。
如果正确实施,事情就会奏效;否则他们会破裂;无论调用该方法的n个线程是从“远程服务器内部”还是从其他系统上的某个其他线程获得它们的命令。
要做到这一点非常明确:你的责任是确保你对该待成为RMI的方法的实现是线程安全的。如果你搞砸了,那么肯定会出问题。但是当你有多个线程调用非线程安全的非RMI方法时,情况也是如此。
答案 2 :(得分:1)
如果我正确理解了这个问题,那么就询问客户端生成的RMI stub 实现是否是线程安全的。
我确信它们是实现了线程安全的,但似乎没有记录在任何地方。我无法在RMI规范中找到任何明确提及存根或不存在线程安全的存根。如果某些内容不是线程安全的,那么通常会记录。
在这个关于Thread safety of RMI stubs的论坛中,有人提到RMI存根是无状态的,因此是线程安全的。问这个问题的人还在Java 6中进行了一些测试,证实了存根的线程安全性,但他也提醒说,因为它不符合规范,所以在未来的版本中可能会有所改变(尽管我认为这不太可能)。 p>