gpt4 book ai didi

java - RMI 线程阻止 JVM 在 main() 完成后退出

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:13:29 30 4
gpt4 key购买 nike

长话短说,在我的应用程序不再需要 RMI 后,我无法关闭几个 Java RMI 的非守护线程。这可以防止 JVM 在 main() 完成时退出。

我知道导出 UnicastRemoteObject 会导致 RMI 保持线程打开,直到您成功调用 UnicastRemoteObject.unexportObject(Object o,boolean force)。下面是一个示例(无需修改即可运行,JVM 将正常退出 - 删除对 unexportObject 的调用,JVM 将永远不会退出):

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");
}
}

此外,您是否创建注册表和/或将远程对象绑定(bind)到它似乎并不重要 - 在这个示例中似乎唯一重要的是任何时候您创建一个 UnicastRemoteObject,您需要调用unexportObject 以防止在您完成后保留任何线程。

在我的应用程序中,我已经确保我已经在我创建的每个 UnicastRemoteObject 上调用了 unexportObject,但 RMI 的“收割者”线程和“连接接受”线程仍然存在,防止我的 JVM 在我的应用程序完成时退出使用 RMI 资源。

除了忘记取消导出 UnicastRemoteObjects 之外,是否还有其他原因可能导致 RMI 遗留线程?

最佳答案

果然,我的代码中有一个错误导致我的(许多)UnicastRemoteObjects 之一在调用应用程序完成使用它时不取消导出自身。所以答案是:

取消导出正在运行的 JVM 中的所有 UnicastRemoteObjects 足以关闭所有 RMI 非守护进程线程。

关于java - RMI 线程阻止 JVM 在 main() 完成后退出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9387203/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com