Можете ли вы прервать BufferedReader.readLine () с помощью Future.cancel (true)? - PullRequest
6 голосов
/ 02 апреля 2012

Допустим, я начал тему, и у меня есть что-то вроде этого:

 ...//initiate all the socket connection
 future = executor.submit
 (  new Runnable()
    {   public void run()
        {   ...
            ...      
            while ((str = in.readLine()) != null)
            {  //do something here

            }

    }

 );

executor является объектом ExecutorService, а in является объектом BufferedReader

Я знаю, что вы можете закрыть сокет из другого потока, чтобы прервать этот поток. Но когда я пытаюсь использовать метод future.cancel (true), даже если он возвращает true, поток кажется работающим, кто-нибудь знает почему? или in.readLine () не может быть прервана таким образом?

Ответы [ 3 ]

10 голосов
/ 02 апреля 2012

Можете ли вы прервать BufferedReader.readLine () с помощью Future.cancel (true)?

Все, что future.cancel(true) делает, это вызывает thread.interrupt() в связанном потоке.Это приведет к тому, что операции sleep() и wait() вызовут InterruptedException, и прервут некоторые специальные каналы NIO .

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

3 голосов
/ 02 апреля 2012

Вы можете закрыть входной поток, чтобы вызвать IOException.В противном случае readLine () может блокироваться навсегда.

Я смотрел на использование JavaLangAccess.blockedOn (), но он выглядит довольно низким уровнем.

1 голос
/ 02 апреля 2012

readLine не генерирует InterruptedException, поэтому на него не повлияет прерывание потока, в котором он выполняется. Вам необходимо явно проверить прерванный статус потока:

        while ((str = in.readLine()) != null)
        {
            if (Thread.interrupted()) {
                //You can deal with the interruption here
            }
        }

Но если он блокируется при выполнении readLine, единственный способ прервать его - закрыть базовый поток, который вызовет IOException.

...