Срок действия реестра RMI, GC и т. Д. - PullRequest
4 голосов
/ 03 февраля 2011

Я работал над внутренним учебным пособием по Java RMI, после просмотра учебного пособия по Sun RMI, и я только вроде понимаю, что происходит. Есть несколько вещей, которые кажутся мне странными, и я хотел бы узнать, что на самом деле происходит, прежде чем дать отзыв об учебнике.

В этом руководстве я напишу следующие компоненты:

  • Интерфейс, скажем RemoteInterface, с методами, к которым мы хотим получить удаленный доступ.
  • Класс, скажем RemoteServer, реализующий RemoteInterface, который в своем конструкторе:
    • Создает объект реестра, вызывая LocateRegistry.createRegistry(PORTNO)
    • Создает объект-заглушку RemoteInterface, вызывая UnicastRemoteObject.exportObject(this, PORTNO) и приводя результат.
    • Связывает заглушку с реестром с помощью registry.rebind(BINDNAME, stub)
  • Класс, скажем, ServerDemo, у которого есть метод main, который просто создает экземпляр RemoteServer.
  • Клиентский класс, который вызывает сервер, используя BINDNAME, и все работает нормально.

Сначала я заметил, что:

  • Сервер продолжает работать после завершения основного метода. Я должен прекратить это явно. На мой взгляд, он должен просто создать объект и затем завершиться, но программа не завершается, и клиент все еще может подключиться.
  • Если я вызываю registry.unbind(BINDNAME) в конструкторе RemoteServer, клиент перестает работать, но сервер по-прежнему не завершает работу.
  • Если я вызову UnicastRemoteObject.unexportObject(this, true); в конструкторе RemoteServer, сервер немедленно завершит работу.

Я хотел бы знать, почему это происходит - хотя если бы это было не так, сервер был бы бесполезен, поскольку он просто немедленно завершил бы работу. (В своем отзыве я предлагаю предложить методы привязки и отмены привязки RemoteServer для вызова ServerDemo, вместо того чтобы выполнять все привязки в конструкторе, никогда не отменять привязку и полагаться на работу сервера по какой-то причине - но сначала я хотелось бы понять, почему это происходит.)

Во-вторых, я заметил, что могу позвонить UnicastRemoteObject.exportObject(this, PORTNO) до , позвонив LocateRegistry.createRegistry(PORTNO), и все по-прежнему работает. Я предполагал, что реестр должен быть настроен, прежде чем мы сможем экспортировать в него, но, очевидно, он не работает так, как я думал.

Мне бы хотелось немного узнать о том, как на самом деле работает exportObject. (Я полагаю, это связано с предыдущим пунктом - почему использование объекта exprted останавливает выполнение программы?)

Кроме того, если я экспортирую и связываю заглушку в одном методе, готовую к извлечению и отмене привязки в другом методе, я хотел бы знать , нужно ли мне явно сохранять ссылку на заглушку в между. (Только BINDNAME необходим для отмены привязки.) Один из моих коллег сообщил о проблемах с GC, и хотя я сам их не заметил, я не могу исключить их, потому что я не совсем понимаю, что происходит.

1 Ответ

0 голосов
/ 03 февраля 2011

RMI по умолчанию работает, запуская TCP-сервер для каждого экспортируемого объекта.Этот сервер прослушивает заданный вами порт и ожидает подключения какого-либо клиента, а затем выполняет вызванный метод.

Таким образом, у вас фактически есть другой поток, прослушивающий этот ServerSocket, который останавливает выход вашего приложения (Java VM).завершает работу, когда не запущены потоки не-deamon).

На самом деле это не имеет никакого отношения к вашему реестру, который, кажется, вообще не используется в вашем случае.

...