Por que definir o bit de interrupção em um Callable

Portanto, este recurso ( http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html ) sugere definir o bit de interrupção em um Thread quando esse Thread não lidar com a interrupção em si, ” para que o código mais acima na pilha de chamadas possa saber da interrupção e responder a ela se quiser . ”

Digamos que eu esteja usando um ExecutorService para executar algo em um Thread diferente. Eu construo um Callable e transmito este Callable em ExecutorService.submit (), que retorna um Future. Se o Callable for interrompido e, em seguida, redefinir o bit de interrupção, o Future associado não lançará uma InterruptedException quando Future.get () for chamado. Então qual seria o propósito de definir o bit interrompido no Callable se este Future for a única maneira que o Thread principal tem access ao Thread gerado.

class MyCallable implements Callable { @Override public String call() { while (!Thread.currentThread().isInterrupted()) { } Thread.currentThread().interrupt(); return "blah"; } } ExecutorService pool = makeService(); Future future = pool.submit(new MyCallable()); // Callable gets interrupted and the Callable resets the interrupt bit. future.get(); // Does not thrown an InterruptedException, so how will I ever know that the Callable was interrupted? 

Você está correto que o sinalizador de interrupção não é passado entre os 2 segmentos neste cenário (que é como o construído em ExecutorService foi projetado por qualquer motivo). Se você quiser que o thread principal veja o status interrompido do callable, então você deve lançar InterruptedException do seu método de chamada.

 class MyCallable implements Callable { @Override public String call() { // ... if(Thread.currentThread().isInterrupted()) { throw new InterruptedException(); } return "blah"; } } 

Observe que você ainda não obterá InterruptedException diretamente de Future.get() nesse cenário. desde que foi lançado pelo callable, ele será empacotado em uma ExecutionException (isto é para que você possa distinguir entre uma interrupção do callable e uma interrupção do thread principal).

Interromper um thread deve terminá-lo, mas de uma maneira menos frágil que kill() . O estado interrompido do encadeamento é verificado apenas durante várias operações de bloqueio.

Se seu thread foi interrompido durante uma dessas operações, uma InterruptedException é lançada. Quando isso acontece, você quer sair de maneira limpa o mais rápido possível. Então, o que um Callable deve fazer se o thread de serviço do executor for interrompido?

Se sua ação for curta, uma opção válida é apenas concluir essa ação normalmente, mas configure o estado interrompido no encadeamento para que o serviço do executor seja encerrado após a conclusão dessa ação.

Se a ação for mais longa, convém lançar uma exceção informando ao chamador que a ação foi interrompida.

    Intereting Posts