Potresti spiegare cosa java.lang.Thread.interrupt()
fa quando viene invocato?
Potresti spiegare cosa java.lang.Thread.interrupt()
fa quando viene invocato?
Risposte:
Thread.interrupt()
imposta lo stato / flag interrotto del thread di destinazione. Quindi il codice in esecuzione nel thread di destinazione PUO 'eseguire il polling dello stato interrotto e gestirlo in modo appropriato. Alcuni metodi che bloccano come Object.wait()
possono consumare immediatamente lo stato interrotto e generare un'eccezione appropriata (di solito InterruptedException
)
L'interruzione in Java non è preventiva. In altri termini, 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 si verifica tramite il Thread.interrupted()
metodo che restituisce lo stato interrotto del thread corrente E cancella il flag di interruzione. Di solito il thread potrebbe quindi fare qualcosa come buttare InterruptedException.
EDIT (dai commenti di Thilo): alcuni metodi API hanno incorporato la gestione degli interrupt. Della parte superiore della mia testa questo include.
Object.wait()
, Thread.sleep()
eThread.join()
java.util.concurrent
struttureInterruptedException
, invece di utilizzare ClosedByInterruptException
.EDIT (dalla risposta di @ thomas-pornin alla stessa domanda per completezza)
L'interruzione del thread è un modo delicato per spingere un thread. È usato per dare ai thread la possibilità di uscire in modo pulito , al contrario di Thread.stop()
quello è più come sparare al filo con un fucile d'assalto.
Che cos'è l'interrupt?
Un interrupt indica 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 viene implementato utilizzando un flag interno noto come stato di interruzione. Richiamare Thread.interrupt imposta questo flag. Quando un thread verifica la presenza di un interrupt invocando il metodo statico Thread.interrupt, lo stato di interruzione viene cancellato. Thread.isInterrupted non statico, utilizzato da un thread per interrogare lo stato di interruzione di un altro, non modifica il flag di stato di interruzione.
Citazione Thread.interrupt()
dall'API :
Interrompe questo thread. Innanzitutto 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 classe Object o di join (), join (long), join (long, int) , sleep (long) o sleep (long, int), metodi di questa classe, quindi il suo stato di interruzione verrà cancellato e riceverà una InterruptedException.
Se questo thread viene 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à un ClosedByInterruptException.
Se questo thread è bloccato in un Selettore, lo stato di interruzione del thread verrà impostato e tornerà immediatamente dall'operazione di selezione, possibilmente con un valore diverso da zero, proprio come se fosse stato invocato il metodo di attivazione del selettore.
Se nessuna delle condizioni precedenti è valida, verrà impostato lo stato di interruzione di questo thread.
Dai un'occhiata a questo per una completa comprensione dello stesso:
http://download.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
Se il thread di destinazione è stato 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 ciò che stava aspettando e riceve invece un'interruzione di eccezione.
Sta completamente al thread stesso (il codice che ha chiamato wait()
) decidere cosa fare in questa situazione. Non termina automaticamente il thread.
A volte viene utilizzato in combinazione con un contrassegno di terminazione. Se interrotto, il thread potrebbe controllare questo flag e quindi chiudersi. Ma ancora una volta, questa è solo una convenzione.
Per completezza, oltre alle altre risposte, se il thread viene interrotto prima che si blocchi Object.wait(..)
o Thread.sleep(..)
ecc., Ciò equivale a essere interrotto immediatamente dopo il blocco su quel metodo , come mostra l'esempio seguente.
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 esegui un ciclo come il seguente e l'interrupt si verifica nel momento esatto in cui il controllo è partito Thread.sleep(..)
e gira intorno al loop, si verificherà comunque l'eccezione. Quindi è assolutamente sicuro fare affidamento sul fatto che InterruptedException viene lanciato in modo affidabile dopo l'interruzione del thread :
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException ie) {
break;
}
}
Thread.interrupt()
imposta lo stato / flag interrotto del thread target su true che, se selezionato usando, 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 del flag . Per ogni thread il valore predefinito dello stato di interrupt è impostato su false . Ogni volta che viene chiamato il metodo interrupt () sul thread, lo stato di interrupt è impostato su true .
public void interrupt ()
Interrompe questo thread.
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 classe Object o di join (), join (long), join (long, int) , sleep (long) o sleep (long, int), metodi di questa classe, quindi il suo stato di interruzione verrà cancellato e riceverà una InterruptedException.
Se questo thread viene 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à un ClosedByInterruptException.
Se questo thread è bloccato in un Selettore, lo stato di interruzione del thread verrà impostato e tornerà immediatamente dall'operazione di selezione, possibilmente con un valore diverso da zero, proprio come se fosse stato invocato il metodo di attivazione del selettore.
Se nessuna delle condizioni precedenti è valida, verrà impostato lo stato di interruzione di questo thread.
L'interruzione di un thread che non è vivo non deve avere alcun effetto.
Produce: SecurityException - se il thread corrente non può modificare questo thread
Un interrupt indica 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
Il metodo Thread.interrupt () imposta il flag interno "stato di interruzione". Di solito quel flag è controllato dal metodo Thread.interrupted ().
Per convenzione, qualsiasi metodo esistente tramite InterruptedException deve cancellare il flag di stato degli interrupt.