Обработка ClosedChannelException в Java - PullRequest
0 голосов
/ 04 ноября 2019

Существует множество подробных советов по правильному обращению с InterruptedException. Применяется ли какой-либо из тех же принципов для обработки ClosedChannelException от вызовов NIO, которые могут быть ClosedByInterruptException? В частности, при перехвате CBIE должен быть вызван Thread.currentThread().interrupt()?

1 Ответ

2 голосов
/ 04 ноября 2019

Вот что говорит документация ClosedByInterruptException ( выделяется моя):

Проверено исключение, полученное потоком, когда другой поток прерывает его, покаон заблокирован в операции ввода-вывода на канале. До того, как сгенерировано это исключение, канал будет закрыт, и будет установлен статус прерывания ранее заблокированного потока.

Кроме того, класс ClosedByInterruptException и егосуперкласс AsynchronousCloseException связан с каналами, которые реализуют InterruptibleChannel. Документация этого интерфейса гласит ( emphasis mine):

Канал, который может быть асинхронно закрыт и прерван.

Канал, который реализует этот интерфейс: асинхронно закрываемый: Если поток заблокирован в операции ввода-вывода на прерываемом канале, тогда другой поток может вызвать метод close канала. Это приведет к тому, что заблокированный поток получит AsynchronousCloseException.

Канал, который реализует этот интерфейс, также прерываемый: Если поток заблокирован в операции ввода-вывода впрерываемый канал, тогда другой поток может вызвать метод interrupt заблокированного потока. Это приведет к закрытию канала, получению заблокированного потока ClosedByInterruptException и установлению статуса прерывания заблокированного потока.

Если статус прерывания потока уже установлен ион вызывает блокирующую операцию ввода-вывода на канале, затем канал закрывается и поток немедленно получает ClosedByInterruptException;его статус прерывания останется установленным.

Канал поддерживает асинхронное закрытие и прерывание, если и только если он реализует этот интерфейс. Это можно проверить во время выполнения, если необходимо, с помощью оператора instanceof.

Другими словами, вам не нужно вызывать Thread.currentThread().interrupt() после перехвата ClosedByInterruptException, потому что канал будет иметьуже установлен или просто поддерживается статус прерывания потока. Я подозреваю, что это поведение определено специально, чтобы не заставлять разработчиков прерывать поток, в отличие от перехвата InterruptedException.

...