我现在正在使用LocateRegistry.createRegistry(1099)而不是在外部进程中使用注册表。但是,注册表会在主程序结束后死掉。例如,如果我创建了一个简单的程序来创建注册表,则该程序将无法正常工作,因为在主执行程序执行之后,代码将结束。我期望LocateRegistry代码创建一个线程,但事实并非如此。这是使用LocateRegistry的正常行为,还是我遗漏了一些东西?

代码示例:

// ommited imports

public class RMITest {
    public static void main(String[] args) {
        LocateRegistry.createRegistry(1099);
        // JVM will exit now!!!
    }
}

RMI服务器启动并突然死机。如何

最佳答案



这不是那么简单。

  • 导出新端口上的第一个对象会创建一个在该端口上监听的线程,而取消导出监听端口上的最后一个对象会导致该线程退出。这适用于所有远程对象,而不仅仅是本地注册表对象。
  • 取消导出可以通过本地GC自动进行,而本地GC又可以通过远程DGC触发。

  • JVM退出是因为您没有将LocateRegistry.createRegistry()返回的值保存在静态变量中,因此它会进行GC处理,因此该对象将不会导出,因此在端口1099上不会导出任何远程对象,因此监听1099的线程退出,因此没有非守护程序线程,因此JVM退出。

    解决方案:将LocateRegistry.createRegistry()的结果存储在静态变量中。当您要退出JVM时,可以使用它取消导出注册表。

    10-06 16:05