在main()完成后,RMI线程阻止JVM退出
总而言之,在我的应用程序不再需要RMI之后,我无法让几个Java RMI的非守护程序线程关闭。这可以防止JVM在main()完成时退出。
To make a long story short, I'm having trouble getting a couple of Java RMI's non-daemon threads to close out after my application no longer needs RMI. This prevents the JVM from exiting when main() completes.
我知道导出 UnicastRemoteObject
s将导致RMI保持线程打开,直到您成功调用 UnicastRemoteObject.unexportObject(Object o,boolean force)
。这是一个例子(运行没有修改,JVM将正常退出 - 删除对unexportObject的调用,JVM永远不会退出):
I understand that exporting UnicastRemoteObject
s will cause RMI to leave threads open until you successfully call UnicastRemoteObject.unexportObject(Object o,boolean force)
. Here's an example (run without modification and the JVM will exit normally - remove the call to unexportObject and the JVM will never exit):
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class TestUnicastRemoteObject{
private static UnicastRemoteObject obj;
private static Registry registry;
public static void main(String[] args) throws Exception{
obj = new UnicastRemoteObject(){
private static final long serialVersionUID = 1L;
};
System.err.println("created UnicastRemoteObject");
System.err.println("creating registry ...");
registry = LocateRegistry.createRegistry(9999);
System.err.println("registry created.");
System.err.println("binding obj to registry ...");
registry.bind("Test", obj);
System.err.println("bound");
UnicastRemoteObject.unexportObject(obj, true);
System.err.println("unexported obj");
}
}
此外,您是否并不重要创建注册表和/或将远程对象绑定到它 - 在这个示例中唯一重要的是,无论何时创建UnicastRemoteObject,都需要调用 unexportObject
为了防止任何线程在你完成之后剩下。
Also, it doesn't seem to matter whether you create the registry and/or bind the remote object to it - the only thing that seems to matter in this example is that any time you create a UnicastRemoteObject, you need to call unexportObject
in order to prevent any threads from remaining after you're done.
在我的应用程序中,我确保在我创建的每个UnicastRemoteObject上都调用了unexportObject,然而,当我的应用程序使用RMI资源完成时,RMI的收割线程和连接接受线程仍然存在,阻止我的JVM退出。
In my application, I've made sure that I've called unexportObject on every UnicastRemoteObject I create, and yet RMI's "reaper" thread and "connection accept" thread still persist, preventing my JVM from exiting when my application is finished using RMI resources.
除了忘记取消导出UnicastRemoteObjects之外,是否有其他可能导致RMI留下线程的东西?
Is there something else that could cause RMI to leave threads behind, aside from forgetting to unexport UnicastRemoteObjects?
果然,我在代码中遇到了一个错误,导致我的(很多)UnicastRemoteObjects中的一个在ca时没有导出自身lling应用程序是利用它完成的。所以答案是:
Sure enough, I had a bug in the code that caused one of my (many) UnicastRemoteObjects to not unexport itself when the calling application was done utilizing it. So the answer is:
在正在运行的JVM中撤消所有UnicastRemoteObjects就足以关闭所有RMI非守护程序线程。
Unexporting all UnicastRemoteObjects within a running JVM is sufficient to close all RMI non-daemon threads.