是java RMI远程对象(服务器)单例吗?

时间:2014-09-12 18:24:58

标签: java spring rmi remoteobject

我一直在使用java RMI一段时间但是我无法弄清楚RMI Remote Stubs(在服务器端)是否是单例?我问的原因是:

假设调用链中较低的RMI实现方法之一具有synchronized方法。如果出于某种原因,同步方法中的逻辑混乱(或挂起),则在尝试访问该同步方法时,未来的RMI调用(来自客户端)也会挂起。只有当RMI存根将成为单例时,这才会成立。如果在客户端的每次远程调用时在服务器端创建一个新对象,这将不会成为问题,因为从另一个对象调用方法并且同步方法将不再是问题。

长话短说。我试图了解JVM如何在服务器端内部维护rmi远程对象以及它们是否是单例。我尝试了许多不同的javadoc,但他们没有在任何地方明确提到它。

感谢任何和所有帮助!

修改 基于一些问题和评论,我正在提炼这个问题:我真正的问题是,服务器端的RMI是否碰巧根据您导出和注册的对象保留某种对象池?你能绑定多个具有相同名称的同一类型的对象(有些模拟一个对象池,其中RMI可以给我任何我注册的对象),或者为了拥有同一个对象的多个实例,我将不得不用不同的名字注册它们

4 个答案:

答案 0 :(得分:4)

首先,“存根”是一个客户端概念,服务器上没有存根。

对于远程对象本身,RMI系统不会为您实例化对象,您可以创建实例并导出它们。您创建对象的一个​​实例,导出该对象,并在特定名称下将其绑定在注册表中。在注册表中从同一名称获取的客户端存根上的所有调用最终都将终止于服务器上的同一对象。

  

是否可以使用相同的名称绑定多个相同类型的对象(稍微模拟一个对象池,其中RMI可以为我提供我注册的任何对象)

不,您只能在给定名称下绑定注册表中的一个对象。但是绑定的对象本身可以是您自己的对象池的代理,例如使用Spring AOP CommonsPoolTargetSource机制。

答案 1 :(得分:2)

存根不是单例,但你的问题实际上是服务器端对象。他们也不是单身人士,除非你自己以这种方式实施。 RMI对此无能为力。

  编辑基于一些问题和评论,我正在提炼这个问题:我真正的问题是,服务器端的RMI是否会根据您导出和注册的对象保留某种对象池?

没有

  

可以使用相同的名称绑定多个相同类型的对象

没有

  

我必须用不同的名字注册它们

您根本不需要注册它们。您需要将一个单独的远程对象绑定到注册表中:将其视为其他远程对象的工厂方法,这些远程对象作为远程方法的结果返回。例如,一个远程Login对象绑定在Registry中,并且有一个login()方法,该方法返回一个远程会话对象,每个登录一个新对象,并有自己的API。

答案 2 :(得分:1)

基于代理设计模式的RMI。

查看here

的内容

RMI Server是一个创建许多远程对象的应用程序。 RMI服务器负责:

  1. 创建远程对象的实例(例如CarImpl instance = new CarImpl());
  2. 导出远程对象;
  3. 将远程对象的实例绑定到RMI注册表。

答案 3 :(得分:0)

来自Java文档:

  

http://docs.oracle.com/javase/7/docs/platform/rmi/spec/rmi-arch3.html

     

由RMI运行时调度到远程对象的方法   实现可能会也可能不会在单独的线程中执行。 RMI   运行时不保证映射远程对象   对线程的调用。由于远程方法调用相同   远程对象可以并发执行,远程对象实现   需要确保其实现是线程安全的。

是的,服务器端方法已同步。该实现是特定于平台的。你不能假设任何关于线程的东西。你当然不能假设远程对象是否是单身人士。

此外,查看远程对象激活可能很有用:

http://docstore.mik.ua/orelly/java-ent/jenut/ch03_06.htm

http://docs.oracle.com/javase/7/docs/api/java/rmi/activation/package-summary.html