@WildfanG_2

Как завершить поток который находиться в бесконечном цикле serverSocket.accept()?

В ознакомительных целях пишу TCP/IP сервер при помощи старых I/O библиотек Java (синхронный подход, блокирующий API с кучей потоков) .

Один из моих потоков отвечает за ожидание и регистрацию новых клиентов. По факту, большую часть времени он сидит в методе accept() серверного сокета. В main() методе/потоке у меня реализовано управление сервера через команды cmd. Проблема состоит в том, что при вызове команды "/stop" которая должна закрывать все потоки данных, сокеты клиентов, сервера и ПОТОКИ, поток который сидит в accept() методе не выполняет выход и из-за него программа продолжает свое выполнение.

Для закрытия потока использовал все доступные (в т.ч. устаревшие) методы класса Thread. В голову пришла идея использовать System.exit(), но почитав на форумах о таком "способе завершения потоков" столкнулся с разными взглядами на этот счет. На практике, это единственный найденный мною метод, который завершает программу при вводе команды "/stop".

Каково ваше мнение? Есть ли адекватные способы завершить такой поток или лучше не использовать вообще этот блокирующий API для сервера?
  • Вопрос задан
  • 382 просмотра
Решения вопроса 1
@ivan19631224
Если интересует конкретно как прерывать ServerSocket.accept(), то, по идее, close() из другого потока вызывает SocketException в методе accept().
Есть ещё вариант (наверное, немного более правильный) при инициализации установить setSoTimeout() и в цикле вызывать accept() перехватывая SocketTimeoutException. В catch блоке проверять некую volatile boolean переменную - признак того что нужно ли остановить поток. Тогда чтобы остановить поток сервера просто меняете эту переменную и поток сам останавливается.
Ещё более правильный способ - использовать nio, желательно с использованием какой-нибудь библиотеки типа netty.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
sergey-gornostaev
@sergey-gornostaev Куратор тега Java
Седой и строгий
Поток должен сам управлять своим жизненным циклом. Вы можете только отправлять ему сигналы через разделяемую волатильную переменную или какой-нибудь примитив синхронизации.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы