在查看了Sun RMI教程后,我一直在进行内部Java RMI教程练习,而我只是有点了解正在发生的事情。有一些事情对我来说似乎很奇怪,我想知道在我对教程提出反馈之前究竟发生了什么。
本教程让我编写以下组件:
LocateRegistry.createRegistry(PORTNO)
UnicastRemoteObject.exportObject(this, PORTNO)
并转换结果来创建存根RemoteInterface对象。registry.rebind(BINDNAME, stub)
首先,我注意到了:
registry.unbind(BINDNAME)
,客户端将停止工作,但服务器仍然无法终止。UnicastRemoteObject.unexportObject(this, true);
,则服务器会立即终止。我想知道为什么会发生这种情况 - 尽管如果不是这样,服务器将无用,因为它会立即终止。 (在我的反馈中,我建议给ServerDemo调用RemoteServer绑定和取消绑定方法,而不是在构造函数中进行所有绑定,从不解除绑定,并且依赖于服务器继续运行由于某种原因 - 但首先我'我想了解它为什么会发生。)
其次,我注意到我可以在调用UnicastRemoteObject.exportObject(this, PORTNO)
之前致电LocateRegistry.createRegistry(PORTNO)
,但一切仍然有效。我认为在我们可以导出之前必须设置注册表,但显然它不像我想象的那样工作。
我想了解一下有关exportObject实际工作方式的一些信息。(我想这与前一点有关 - 为什么有一个对象被删除会阻止程序结束?)
另外,如果我在一个方法中导出并绑定存根,准备在另一个方法中取消导出和取消绑定,我想知道是否需要明确保留对存根的引用之间。 (只有BINDNAME才能解开。)我的一位同事报告了GC问题,虽然我没有注意到任何问题,但我不能排除它们,因为我不知道发生了什么。
答案 0 :(得分:0)
默认情况下,RMI通过为每个导出的对象运行TCP服务器来工作。此服务器侦听您给出的端口,并等待某个客户端连接到那里,然后执行被调用的方法。
所以你有效地让另一个Thread监听这个ServerSocket,这会阻止你的应用程序退出(当没有非deamon线程运行时,Java VM退出)。
事实上,这与您的注册表完全没有关系,在您的情况下似乎根本没有使用它。