Java RMI注册表生存期、GC等
在看了Sun RMI教程之后,我一直在做一个内部Java RMI教程练习,我只是有点了解发生了什么。有一些事情对我来说似乎很奇怪,我想在对教程给出反馈之前知道到底发生了什么 本教程让我编写以下组件:Java RMI注册表生存期、GC等,java,garbage-collection,rmi,Java,Garbage Collection,Rmi,在看了Sun RMI教程之后,我一直在做一个内部Java RMI教程练习,我只是有点了解发生了什么。有一些事情对我来说似乎很奇怪,我想在对教程给出反馈之前知道到底发生了什么 本教程让我编写以下组件: 一个接口,比如说RemoteInterface,包含我们希望远程访问的方法 实现RemoteInterface的类,如RemoteServer,在其构造函数中: 通过调用LocateRegistry.createRegistry(PORTNO) 通过调用UnicastRemoteObject.e
- 一个接口,比如说RemoteInterface,包含我们希望远程访问的方法
- 实现RemoteInterface的类,如RemoteServer,在其构造函数中:
- 通过调用
LocateRegistry.createRegistry(PORTNO)
- 通过调用
并强制转换结果来创建存根RemoteInterface对象UnicastRemoteObject.exportObject(this,PORTNO)
- 使用注册表重新绑定(BINDNAME,stub)
- 通过调用
- 一个类,比如ServerDemo,它有一个只创建RemoteServer实例的主方法
- 使用BINDNAME调用服务器的客户机类,一切正常
- 主方法完成后,服务器继续运行。我必须明确地终止它。在我看来,它应该只是创建一个对象,然后完成,但程序不会终止,客户端仍然可以连接
- 如果我在RemoteServer构造函数中调用
,客户端将停止工作,但服务器仍不会终止registry.unbind(BINDNAME)
- 如果我调用
在RemoteServer构造函数中,服务器立即终止UnicastRemoteObject.unexportObject(this,true)
LocateRegistry.createRegistry(PORTNO)
之前,我可以调用UnicastRemoteObject.exportObject(这个,PORTNO)
,并且一切仍然正常。我认为必须先建立注册中心,然后才能导出到它,但很明显,它并没有按照我的想法工作
我想了解一下exportObject实际上是如何工作的。(我想这与前一点有关-为什么导出对象会阻止程序结束?)
另外,如果我在一个方法中导出并绑定存根,准备在另一个方法中取消导出并解除绑定,我想知道是否需要在两者之间显式保留存根的引用。(只有BINDNAME是解除绑定所必需的。)我的一位同事报告了GC问题,虽然我自己没有注意到任何问题,但我不能排除它们,因为我没有真正了解发生了什么。默认情况下,RMI通过为每个导出的对象运行TCP服务器来工作。此服务器侦听您给定的端口,并等待某个客户端连接到该端口,然后执行被调用的方法 因此,您实际上有另一个线程在侦听这个ServerSocket,这会阻止您的应用程序退出(当没有非deamon线程运行时,Java VM会退出)
事实上,这与您的注册表没有任何关系,在您的案例中似乎根本没有使用注册表。该注册表用于客户端-它调用
LocateRegistry.getRegistry(HOSTNAME,PORTNO)
,然后使用该注册表查找导出的对象。但是我注意到,我可以不使用UnicastRemoteObject.exportObject
调用并绑定RemoteServer对象而不是存根,并且除了在客户端而不是服务器上准备的一些System.out
输出外,其他一切都可以正常工作。。。现在我更困惑了:/