2015-10-22 3 views
5

Вот фрагмент кода:Это прерывание() необходимо?

public class LogService { 

    public void stop() { 
     synchronized (this) { isShutdown = true; } 
     loggerThread.interrupt(); /* Is it necesarry? */ 
    } 

    public void log(String msg) throws InterruptedException { 
     synchronized (this) { 
      if (isShutdown) 
      throw new IllegalStateException(...); 
      ++reservations; 
     } 
     queue.put(msg); 
    } 

    private class LoggerThread extends Thread { 
     public void run() { 
      try { 
       while (true) { 
        try { 
         synchronized (LogService.this) { 
          if (isShutdown && reservations == 0) 
           break; 
         } 
         String msg = queue.take(); 
         synchronized (LogService.this) { 
         --reservations; 
         } 
         writer.println(msg); 
        } catch (InterruptedException e) { } /* Do nothing */ 
       } 
      } finally { 
       writer.close(); 
      } 
     } 
    } 
} 

В приведенном выше коде, даже если положить LoggerThread.interrupt() в остановке() метод, прерывание просто быть пойманной нить и ничего не делать.

Значит, LoggerThread.interrupt() необходимо?

ответ

6

Да, это необходимо. Если очередь пуста, это заявление String msg = queue.take(); будет блокироваться до тех пор, пока элемент не будет помещен в очередь или он не будет прерван.

Если вы хотите гарантировать, что нить не зависает, вам необходимо ее прервать.

Однако, похоже, глюк: если reservations не 0 при вызове метода close И очередь пуста, то кажется, что ваш цикл будет продолжать идти и повесить на queue.take() на время цикла итерации после перерыва.

+1

Удаление моего ответа как вашего более точно. –

+0

Итак, 'InterruptedException' может быть передано' queue.take() '? – user2916610

+0

@ user2916610 исключение не передается методу - код в 'queue.take()' проверяет, прерывается ли поток на регулярной основе и генерирует исключение InterruptedException, если поток прерывается. – assylias

Смежные вопросы