Cosa fa java.lang.Thread.interrupt ()?

Potresti spiegare cosa fa java.lang.Thread.interrupt() quando viene richiamato?

Thread.interrupt() imposta lo stato / flag interrotto del thread di destinazione. Quindi il codice in esecuzione in tale thread di destinazione POTREBBE eseguire il polling dello stato interrotto e gestirlo appropriatamente. Alcuni metodi che bloccano come Object.wait() possono consumare immediatamente lo stato interrotto e generare un’eccezione appropriata (in genere InterruptedException )

L’interruzione in Java non è preventiva. In altre parole, entrambi i thread devono cooperare per elaborare correttamente l’interrupt. Se il thread di destinazione non esegue il polling dello stato interrotto, l’interrupt viene effettivamente ignorato.

Il polling avviene tramite il metodo Thread.interrupted() che restituisce lo stato interrotto del thread corrente e cancella il flag di interrupt. Di solito il thread potrebbe fare qualcosa come lanciare InterruptedException.

EDIT (dai commenti Thilo): alcuni metodi API hanno incorporato la gestione degli interrupt. Di cima alla mia testa questo include.

  • Object.wait()/Thread.sleep()
  • La maggior parte delle strutture java.util.concurrent
  • Java NIO (ma non java.io) e NON usa InterruptedException , utilizzando invece ClosedByInterruptException .

EDIT (dalla risposta di @ thomas-pornin alla stessa identica domanda per completezza)

L’interruzione del filo è un modo delicato per spingere un filo. È usato per dare ai thread la possibilità di uscire in modo pulito , al contrario di Thread.stop() che è più come sparare alla discussione con un fucile d’assalto.

Cos’è l’interruzione?

Un interrupt è un’indicazione a un thread che dovrebbe interrompere ciò che sta facendo e fare qualcos’altro. Spetta al programmatore decidere esattamente come un thread risponde a un interrupt, ma è molto comune che il thread termini.

Come viene implementato?

Il meccanismo di interruzione è implementato utilizzando un flag interno noto come stato dell’interrupt. Invocare Thread.interrupt imposta questo flag. Quando un thread verifica la presenza di un interrupt richiamando il metodo statico Thread.interrupted, lo stato di interruzione viene cancellato. Thread.isInterrupted non statico, che viene utilizzato da un thread per interrogare lo stato di interruzione di un altro, non modifica il flag di stato dell’interrupt.

Citazione Thread.interrupt() :

Interrompe questa discussione Innanzitutto viene richiamato il metodo checkAccess di questo thread, che può causare il lancio di SecurityException.

Se questo thread è bloccato in una chiamata dei metodi wait (), wait (long) o wait (long, int) della class Object, o di join (), join (long), join (long, int) , sleep (long), o sleep (long, int), metodi di questa class, quindi il suo stato di interrupt verrà cancellato e riceverà una InterruptedException.

Se questo thread è bloccato in un’operazione I / O su un canale interrompibile, il canale verrà chiuso, verrà impostato lo stato di interruzione del thread e il thread riceverà ClosedByInterruptException.

Se questo thread è bloccato in un selettore, verrà impostato lo stato di interruzione del thread e verrà restituito immediatamente dall’operazione di selezione, possibilmente con un valore diverso da zero, proprio come se il metodo di triggerszione del selettore fosse invocato.

Se nessuna delle condizioni precedenti è valida, verrà impostato lo stato di interruzione di questo thread.

Controlla questo per una comprensione completa dello stesso:

http://download.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

Per completezza, oltre alle altre risposte, se il thread viene interrotto prima che blocchi su Object.wait(..) o Thread.sleep(..) ecc., Questo equivale a essere interrotto immediatamente dopo il blocco su quel metodo , come mostra il seguente esempio.

 public class InterruptTest { public static void main(String[] args) { Thread.currentThread().interrupt(); printInterrupted(1); Object o = new Object(); try { synchronized (o) { printInterrupted(2); System.out.printf("A Time %d\n", System.currentTimeMillis()); o.wait(100); System.out.printf("B Time %d\n", System.currentTimeMillis()); } } catch (InterruptedException ie) { System.out.printf("WAS interrupted\n"); } System.out.printf("C Time %d\n", System.currentTimeMillis()); printInterrupted(3); Thread.currentThread().interrupt(); printInterrupted(4); try { System.out.printf("D Time %d\n", System.currentTimeMillis()); Thread.sleep(100); System.out.printf("E Time %d\n", System.currentTimeMillis()); } catch (InterruptedException ie) { System.out.printf("WAS interrupted\n"); } System.out.printf("F Time %d\n", System.currentTimeMillis()); printInterrupted(5); try { System.out.printf("G Time %d\n", System.currentTimeMillis()); Thread.sleep(100); System.out.printf("H Time %d\n", System.currentTimeMillis()); } catch (InterruptedException ie) { System.out.printf("WAS interrupted\n"); } System.out.printf("I Time %d\n", System.currentTimeMillis()); } static void printInterrupted(int n) { System.out.printf("(%d) Am I interrupted? %s\n", n, Thread.currentThread().isInterrupted() ? "Yes" : "No"); } } 

Produzione:

 $ javac InterruptTest.java $ java -classpath "." InterruptTest (1) Am I interrupted? Yes (2) Am I interrupted? Yes A Time 1399207408543 WAS interrupted C Time 1399207408543 (3) Am I interrupted? No (4) Am I interrupted? Yes D Time 1399207408544 WAS interrupted F Time 1399207408544 (5) Am I interrupted? No G Time 1399207408545 H Time 1399207408668 I Time 1399207408669 

Implicazione: se si Thread.sleep(..) loop come il seguente e l’interruzione si verifica nel momento esatto in cui il controllo ha lasciato Thread.sleep(..) e sta girando attorno al ciclo, l’eccezione si verificherà ancora. Quindi è perfettamente sicuro affidarsi a InterruptedException che viene lanciato in modo affidabile dopo che il thread è stato interrotto :

 while (true) { try { Thread.sleep(10); } catch (InterruptedException ie) { break; } } 

Se il thread di destinazione è in attesa (chiamando wait() , o altri metodi correlati che essenzialmente fanno la stessa cosa, come sleep() ), verrà interrotto, il che significa che smette di aspettare quello che stava aspettando e invece riceve una InterruptedException.

È completamente in linea con il thread stesso (il codice che ha chiamato wait() ) per decidere cosa fare in questa situazione. Non termina automaticamente il thread.

A volte è usato in combinazione con un flag di terminazione. Una volta interrotto, il thread potrebbe controllare questo flag e quindi chiudersi. Ma di nuovo, questa è solo una convenzione.

public void interrupt ()

Interrompe questa discussione

A meno che il thread corrente non si interrompa da solo, il che è sempre consentito, viene invocato il metodo checkAccess di questo thread, che può causare il lancio di SecurityException.

Se questo thread è bloccato in una chiamata dei metodi wait (), wait (long) o wait (long, int) della class Object, o di join (), join (long), join (long, int) , sleep (long), o sleep (long, int), metodi di questa class, quindi il suo stato di interrupt verrà cancellato e riceverà una InterruptedException.

Se questo thread è bloccato in un’operazione I / O su un canale interrompibile, il canale verrà chiuso, verrà impostato lo stato di interruzione del thread e il thread riceverà ClosedByInterruptException.

Se questo thread è bloccato in un selettore, verrà impostato lo stato di interruzione del thread e verrà restituito immediatamente dall’operazione di selezione, possibilmente con un valore diverso da zero, proprio come se il metodo di triggerszione del selettore fosse invocato.

Se nessuna delle condizioni precedenti è valida, verrà impostato lo stato di interruzione di questo thread.

Interrompere un thread che non è vivo non deve avere alcun effetto.

Genera: SecurityException – se il thread corrente non può modificare questo thread

Thread.interrupt() imposta lo stato / flag interrotto del thread di destinazione su true che, se selezionato con Thread.interrupted() può aiutare a fermare il thread infinito. Consultare http://www.yegor256.com/2015/10/20/interrupted-exception.html

L’interruzione del thread si basa sullo stato di interruzione flag. Per ogni valore di default del thread di stato dell’interrupt è impostato su false . Ogni volta che il metodo interrupt () viene chiamato su thread, lo stato dell’interrupt è impostato su true .

  1. Se interrupt status = true (interrupt () già chiamato su thread), quel particolare thread non può andare in sleep. Se viene chiamato sleep, viene generata un’eccezione interrotta. Dopo aver lanciato nuovamente l’eccezione, il flag è impostato su false.
  2. Se thread sta già dormendo e viene chiamato interrupt () , il thread uscirà dallo stato di sospensione e genererà un’eccezione interrotta.

Un interrupt è un’indicazione a un thread che dovrebbe interrompere ciò che sta facendo e fare qualcos’altro. Spetta al programmatore decidere esattamente come un thread risponde a un interrupt, ma è molto comune che il thread termini. Un ottimo riferimento: https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html