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