Короче говоря, у меня возникли проблемы с закрытием нескольких потоков, не являющихся демонами Java RMI, после того как мое приложение больше не нуждается в RMI.Это предотвращает выход JVM после завершения main ().
Я понимаю, что экспорт UnicastRemoteObject
s заставит RMI оставить потоки открытыми, пока вы не вызовете UnicastRemoteObject.unexportObject(Object o,boolean force)
.Вот пример (запускается без изменений, и JVM завершает свою работу нормально - удалите вызов uninportObject, и 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");
}
}
Кроме того, не важно, создаете ли вы реестри / или привязать к нему удаленный объект - единственное, что, кажется, имеет значение в этом примере, - это то, что каждый раз, когда вы создаете UnicastRemoteObject, вам нужно вызывать unexportObject
, чтобы предотвратить сохранение потоков после того, как вы закончите.
В своем приложении я удостоверился, что вызывалexportObject для каждого создаваемого мной UnicastRemoteObject, и все же поток RMI "reaper" и поток "connection accept" все еще сохраняются, предотвращая выход моей JVM, когда мойПриложение завершено с использованием ресурсов RMI.
Есть ли что-то еще, что может привести к тому, что RMI оставит потоки позади, кроме того, что забудет удалить UnicastRemoteObjects?