Прерывать поток в DatagramSocket.receive
Я создаю приложение, которое слушает как TCP, так и UDP, и я столкнулся с некоторыми проблемами с моим механизмом отключения. Когда я вызываю Thread.interrupt()
в каждом из потоков прослушивания, поток TCP прерывается от прослушивания, тогда как прослушиватель UDP - нет. Чтобы быть конкретным, поток TCP использует ServerSocket.accept()
, который просто возвращает (без фактического подключения). В то время как поток UDP использует DatagramSocket.receive()
и не выходит из этого метода.
Является ли это проблемой в моей JRE, моей ОС или мне просто нужно перейти на (Datagram)Socket.close()
?
UPDATE: я нашел анализ проблемы. Он подтверждает, что поведение несовместимо.
Ответы
Ответ 1
Общей идиомой прерывания IO сети является закрытие канала. Это будет хорошей ставкой, если вам нужно эффективно прервать его, пока он ждет при отправке или получении.
public class InterruptableUDPThread extends Thread{
private final DatagramSocket socket;
public InterruptableUDPThread(DatagramSocket socket){
this.socket = socket;
}
@Override
public void interrupt(){
super.interrupt();
this.socket.close();
}
}
Ответ 2
Насколько я знаю, close()
- это правильный способ прервать заблокированный сокет. Прерывание и сохранение того, что, возможно, уже сделало частичное чтение или запись, делает вещи излишне сложными. Легче всего иметь дело с результатом "успеха" или "сдаться".
Ответ 3
DatagramSocket.receive
блокирует, пока не получит датаграмму. Вероятно, вам нужно использовать setSoTimeout
, чтобы сделать это таймаутом.