Perché Thread.isInterrupted () restituisce sempre false?

Ho trovato il metodo di JavaDoc:

Restituisce: true se questo thread è stato interrotto; falso altrimenti.

Penso che ci sia qualcosa di sbagliato nella mia comprensione del metodo. Inoltre, potrei fraintendere il concetto di “interruzione” in Thread.

Qualsiasi spiegazione è ben accetta! Grazie!

Snippet di codice:

Nella definizione del thread:

public void run() { try { //Do something } catch (InterruptedException e) { System.out.println(isInterrupted());//Always false return; } } 

invocare:

 theThread.interrupt(); 

Una volta generata l’eccezione, il thread non è più in uno stato interrotto.

Questo comportamento è in genere documentato in metodi che generano quell’eccezione. Ad esempio, javadoc per Object.wait() dice:

InterruptedException – se qualsiasi thread ha interrotto il thread corrente prima o mentre il thread corrente era in attesa di una notifica, lo stato interrotto del thread corrente viene cancellato quando viene generata questa eccezione.

In effetti, il javadoc per l’eccezione stessa dice questo:

“Occasionalmente un metodo potrebbe voler verificare se il thread corrente è stato interrotto e, in tal caso, lanciare immediatamente questa eccezione. Il seguente codice può essere utilizzato per ottenere questo effetto:

 if (Thread.interrupted()) // Clears interrupted status! throw new InterruptedException(); 

Nota come sottolineano che il flag deve essere cancellato prima che l’eccezione venga lanciata.


Perché è stato progettato per funzionare in questo modo? Dovresti chiedere ai progettisti, ma mi aspetto che abbiano pensato che un gestore di eccezioni dovrebbe gestire la situazione e che quindi non ci dovrebbe essere alcuna necessità che il flag sia ancora impostato in quel punto. (Se il gestore non gestisce completamente la situazione, può rilanciare l’eccezione o chiamare Thread.getCurrentThread.interrupt() per impostare nuovamente il flag.)

Aggiungendo alla risposta di cdhowie, uno schema standard prevede che il thread gestisca l’interruzione. Questo è utile con gli Executor , quando il codice in esecuzione non “possiede” il Thread e non dovrebbe intralciare l’interruzione (a meno che tu non sappia davvero cosa stai facendo)

 public void run() { try { //Do something } catch (InterruptedException e) { // Do whatever local clean up you need to ... // Then let the owning Thread know it's been interrupted, so it too can clean up Thread.currentThread().interrupt(); // } } 

Dovresti controllare isInterrupted () nel tuo codice, ad esempio da un loop. Se il thread è stato interrotto, puoi quindi interrompere InterruptedException per interrompere l’esecuzione.

Nel tuo esempio se hai catturato InterruptedException puoi essere sicuro che è stato interrotto e non devi controllare quel metodo.