如何在空闲N秒后关闭RMI UnicastRemoteObject

时间:2014-05-11 06:30:43

标签: java rmi

我有一个应用程序,我正在尝试添加RMI功能。

启动应用程序很昂贵,所以我想在第一次客户端调用时启动RMI服务器,并在一段时间不活动后关闭,比如在1分钟后关闭。

我从客户端启动服务器,如下所示:

try {
  service = (RMIService) Naming.lookup("rmi://localhost:" + RMIServiceImpl.RMI_PORT + "/" + RMIServiceImpl.RMI_NAME);
}
catch (ConnectException ex) {
  new RMIServiceImpl(args);
  service = (RMIService) Naming.lookup("rmi://localhost:" + RMIServiceImpl.RMI_PORT + "/" + RMIServiceImpl.RMI_NAME);
}

并且在RMIServiceImpl中我有

try {

    rmiRegistry = LocateRegistry.createRegistry(RMI_PORT);
    rmiRegistry.rebind(RMI_NAME, this);

    System.out.println("Registered  RMI Service " + RMI_NAME + " on port " + RMI_PORT);
}
catch (Exception ex) { ex.printStackTrace(); }

long idle = 1000 * 60;
long lastCall = System.currentTimeMillis();  // updated with each client call
do {
    try { Thread.sleep(1000); } catch (InterruptedException e) {}
}
while (System.currentTimeMillis() < (lastCall + idle));

if (rmiRegistry != null)
    rmiRegistry.unbind(RMI_NAME);  // (1)

UnicastRemoteObject.unexportObject(this, true);  // (2)

问题是RMIServiceImpl永远不会退出,JVM会继续运行。

在第(1)点我得到一个NotBoundException,我不确定为什么因为该名称被绑定了?

在第(2)点我得到一个WriteAbortedException:写入中止; java.io.NotSerializableException:sun.misc.Launcher $ AppClassLoader

但在任何一种情况下服务都不会关闭......

有什么想法吗? TIA!

1 个答案:

答案 0 :(得分:1)

让您的远程对象实现Unreferenced接口,并在unreferenced()方法实现中取消导出

UnicastRemoteObject.unexportObject(this, true);

这将在DGC间隔到期时启动。