select (с набором маски чтения) вернется с указателем на маркер, но если вы используете ioctl * для проверки количества байтов, ожидающих чтения, оно будет равно нулю. Это признак того, что сокет был отключен.
Это отличная дискуссия по различным методам проверки того, что клиент отключился: Стивен Клири, обнаружение полуоткрытых (отброшенных) соединений .
* для Windows использовать ioctlsocket.
Если вы хотите завершить поток, то достаточно просто вернуться. Вам НЕ нужно вызывать Thread.currentThread().interrupt()
(хотя это не сделает ничего плохого. Просто это не нужно). Это потому, что interrupt()
в основном используется для уведомления владельца потока (ну, не на 100% точно, но вроде того). Поскольку вы являетесь владельцем потока и решили его завершить, уведомлять некого, поэтому вам не нужно его вызывать.
Кстати, почему в первом случае нам нужно использовать currentThread? Разве Thread не ссылается на текущий поток?
Да, не ссылается. Я думаю, это может сбить с толку, потому что, например, Thread.sleep() влияет на текущий поток, но Thread.sleep() - это статический метод.
Если вы НЕ являетесь владельцем потока (например, если вы не расширили Thread
и не создали Runnable
и т.д.), вы должны сделать
Thread.currentThread().interrupt();
return;
Таким образом, любой код, вызвавший ваш runnable, будет знать, что поток прерван = (обычно) он должен прекратить все свои действия и завершиться. Как я уже говорил, это всего лишь механизм коммуникации. Владелец может просто игнорировать прерванный статус и ничего не делать... но если вы установите прерванный статус, кто-то может поблагодарить вас за это в будущем.
По той же причине вы никогда не должны делать
Catch(InterruptedException ie){
//ignore
}
Потому что если вы это сделаете, вы остановите сообщение на этом месте. Вместо этого следует сделать
Catch(InterruptedException ie){
Thread.currentThread().interrupt();//preserve the message
return;//Stop doing whatever I am doing and terminate
}
Если метод run завершается, поток завершается.
Если вы используете цикл, правильный способ выглядит следующим образом:
// In your imlemented Runnable class:
private volatile boolean running = true;
public void run()
{
while (running)
{
...
}
}
public void stopRunning()
{
running = false;
}
Конечно, возврат - лучший способ.
Thread - это класс, а не экземпляр; currentThread () - статический метод, который возвращает экземпляр Thread, соответствующий вызывающему потоку.
Используйте (2). interrupt () для нормального использования немного жестока.
Если вы находитесь на верхнем уровне - или можете чисто получить на верхний уровень - потока, тогда просто возвратиться будет хорошо. Создание исключения не так чисто, так как вам нужно убедиться, что ничто не будет перехватывать исключение и игнорировать его.
Причина, по которой вам нужно использовать Thread.currentThread ()
для вызова interrupt ()
, заключается в том, что interrupt ()
является методом экземпляра - вы необходимо вызвать его в потоке, который вы хотите прервать, который в вашем случае является текущим потоком. Обратите внимание, что прерывание будет замечено только в следующий раз, когда поток будет заблокирован (например, для ввода-вывода или для монитора) в любом случае - это не означает, что исключение будет сгенерировано немедленно.