Quando o Java's Thread.sleep lança InterruptedException?

110

Quando o Java's Thread.sleep lança InterruptedException? É seguro ignorar isso? Não estou fazendo nenhum multithreading. Só quero esperar alguns segundos antes de tentar novamente alguma operação.

Manki
fonte
1
Depende de qual sentido você quer dizer "ignorar". InterruptedExceptioné uma exceção capturada, então você não pode compilar a menos que você lidar com ou declarar este tipo de exceção em qualquer método que une ou acomoda um Threadou chamadas wait()sobre Object.
8bitjunkie

Respostas:

41

Você geralmente NÃO deve ignorar a exceção. Dê uma olhada no seguinte artigo:

Não engula interrupções

Às vezes, lançar InterruptedException não é uma opção, como quando uma tarefa definida por Runnable chama um método interruptível. Nesse caso, você não pode relançar InterruptedException, mas também não quer fazer nada. Quando um método de bloqueio detecta interrupção e lança InterruptedException, ele limpa o status interrompido. Se você capturar InterruptedException, mas não puder relançá-la, deve preservar a evidência de que a interrupção ocorreu para que o código mais acima na pilha de chamadas possa saber da interrupção e responder a ela, se desejar. Esta tarefa é realizada chamando interrupt () para "reinterromper" o encadeamento atual, conforme mostrado na Listagem 3. No mínimo, sempre que você capturar InterruptedException e não relançar, interrompa o encadeamento atual antes de retornar.

public class TaskRunner implements Runnable {
    private BlockingQueue<Task> queue;

    public TaskRunner(BlockingQueue<Task> queue) { 
        this.queue = queue; 
    }

    public void run() { 
        try {
             while (true) {
                 Task task = queue.take(10, TimeUnit.SECONDS);
                 task.execute();
             }
         }
         catch (InterruptedException e) { 
             // Restore the interrupted status
             Thread.currentThread().interrupt();
         }
    }
}

Veja o artigo completo aqui:

http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html?ca=drs-

Benny Bottema
fonte
38

Se um InterruptedExceptionfor lançado, significa que algo deseja interromper (geralmente encerrar) esse segmento. Isso é disparado por uma chamada ao interrupt()método threads . O método de espera detecta isso e lança umInterruptedException para que o código catch possa lidar com a solicitação de encerramento imediatamente e não tenha que esperar até que o tempo especificado termine.

Se você usá-lo em um aplicativo single-threaded (e também em alguns aplicativos multithread), essa exceção nunca será disparada. Ignorá-lo por ter uma cláusula catch vazia, eu não recomendaria. O lançamento de InterruptedExceptionlimpa o estado interrompido da discussão, então, se não for tratada corretamente, essas informações serão perdidas. Portanto, eu proporia executar:

} catch (InterruptedException e) {
  Thread.currentThread().interrupt();
  // code for stopping current task so thread stops
}

O que define esse estado novamente. Depois disso, termine a execução. Este seria um comportamento correto, mesmo difícil nunca usado.

O que pode ser melhor é adicionar isto:

} catch (InterruptedException e) {
  throw new RuntimeException("Unexpected interrupt", e);
}

... declaração para o bloco catch. Isso basicamente significa que isso nunca deve acontecer. Portanto, se o código for reutilizado em um ambiente onde isso possa acontecer, ele reclamará.

cristãos
fonte
5
Asserções em Java estão desativadas por padrão . Portanto, é melhor apenas jogar um RuntimeException.
Evgeni Sergeev
11

O boletim informativo Java Specialists (que posso recomendar sem reservas) tinha um artigo interessante sobre isso e como lidar com o InterruptedException. Vale a pena ler e digerir.

Brian Agnew
fonte
1
O que isso quer dizer?
theonlygusti
5

Métodos como sleep()e wait()de classe Threadpodem lançar um InterruptedException. Isso acontecerá se algum outro threadquiser interromper o threadque está esperando ou dormindo.

user7805041
fonte
3

Uma maneira sólida e fácil de manipulá-lo em código de thread único seria capturá-lo e recuperá-lo em uma RuntimeException, para evitar a necessidade de declará-lo para cada método.

azul da estrela
fonte
-7

O InterruptedExceptiongeralmente é lançado quando um sono é interrompido.

BrutalOst
fonte
13
Isso está errado, pois não é o sono em si que é interrompido, mas o Thread que o executa. Interrompido é um estado de thread. Isso apenas leva à saída do método do sono.
ubuntudroid