我有一个应用程序,我正在尝试添加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!
答案 0 :(得分:1)
让您的远程对象实现Unreferenced
接口,并在unreferenced()
方法实现中取消导出
UnicastRemoteObject.unexportObject(this, true);
这将在DGC间隔到期时启动。