2013-04-08 3 views
6

Questa è una domanda sulla vecchia Java quando stavamo creando i nostri thread. Alcuni metodi come Thread.sleep(100) generano uno InterruptedException quando viene interrotto da un altro thread. Ora, a quanto ho capito, un'interruzione significa che un altro thread sta dicendo: Lasciami prendere il controllo ora.Perché InterruptedException è un'eccezione controllata?

Quando ciò accade, perché Java vuole che ci occupiamo di InterruptedException?

Il programmatore non dovrebbe nemmeno aver bisogno di preoccuparsi quando i fili si interrompono a vicenda. Dovrebbe essere solo in grado di dividere il lavoro tra i fili e di essere notificato quando è fatto. Quindi, qual è la ragione per cui Java ci vuole trattare con InteruptedException? Per lo meno dovrebbe essere RuntimeException

+0

Suppongo che ciò consenta allo sviluppatore di intraprendere l'azione appropriata ogni volta che il thread viene interrotto. Il thread potrebbe svolgere alcune attività critiche e potrebbe essere necessario gestire l'interruzione in modo corretto. –

+0

Per costringerti a prenderlo. – EJP

+2

Si prega di non chiuderlo. Ci sono alcune grandi risposte qui – Victor

risposta

6

Il programmatore non dovrebbe nemmeno bisogno di preoccuparsi quando i fili sono interrompendosi a vicenda

Questo non è vero. Ci sono molte, molte situazioni in cui vuoi sapere che è stata richiesta un'interruzione, ma la ignorerai per un po 'per finire il lavoro che stai facendo.

Ad esempio, si supponga che un thread apra un file e inizi a scrivere alcuni dati. Questo thread, quindi, blocca, in attesa del resto dei dati da calcolare. Supponiamo che un secondo thread cerchi di interrompere il primo. Cosa dovrebbe fare? Semplicemente muori, e forse finisci con un file corrotto, incompleto? Dovrebbe essere ripulito eliminando il file che ha iniziato a scrivere? Dovrebbe ignorare la richiesta di interruzione e aspettare solo la fine dei dati che deve scrivere? Dovrebbe scrivere qualcosa che significa "Sono stato interrotto qui", in modo che possa continuare il suo lavoro da quel punto la prossima volta?

In uno scenario diverso, si supponga di disporre di un server HTTP. Supponiamo che gli utenti stiano accedendo al tuo server e, per esempio, scaricando un grosso file da esso. Vuoi fermare il server. L'applicazione proverà quindi ad interrompere tutti i thread di lavoro. Cosa dovrebbero fare? Basta interrompere i download? O dovrebbero aspettare che gli utenti finiscano di scaricare i loro file e solo dopo che dovrebbero morire, senza accettare altre richieste? Entrambi gli scenari sono ugualmente validi.

Come vedete, ci sono troppi scenari possibili e sarebbe terribile se non avessimo modo di sapere che è stata richiesta un'interruzione. A volte, lascerai semplicemente che il thread muoia. A volte, è necessario ripulire l'ambiente. A volte, vuoi che finisca la richiesta su cui sta lavorando, ma non accetti altre richieste.

+2

Non sei sicuro di come questo risponda alla domanda: tutto ciò che hai scritto sopra sarebbe altrettanto facilmente realizzabile se InterruptedException fosse deselezionato. – Peter

+0

@Peter Il fatto che sia controllato richiede l'utente della tua API che può lanciare l'eccezione per gestirlo esplicitamente in qualche modo. Se fosse deselezionato e non catturato, si limiterebbe a gettare l'eccezione e, eventualmente, a terminare il programma, il che significa che tutti i casi sopra riportati di file corrotti e connessioni interrotte sono possibili. Renderlo controllato è un modo per assicurarsi che l'utente non si faccia sfuggire la parte importante della gestione dell'eccezione. –

3

Sembra che tu stia mescolando tra lo schedulatore e l'interruzione.

Uno scheduler di thread è piuttosto un sistema nativo, che divide i processi da più thread in processi. Se sono attivi troppi thread, lo scheduler funzionerà in modo asincrono. In altre parole lasciatemi prendere in carico per ora potrebbe essere proprio vero.

Un interrupt significa, uscire da ciò che si sta facendo attualmente e non tornare ad esso. Il modo più pratico per implementarlo è un'eccezione.

+0

Secondo Oracle, http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html, * "Un interrupt significa, esci da ciò che stai facendo e ** non tornare ad esso * * "*, non è del tutto corretto. Dice: "Un interrupt è un'indicazione a un thread che dovrebbe interrompere ciò che sta facendo e fare qualcos'altro. ** Sta al programmatore decidere esattamente come un thread risponde a un interrupt **". non esiste un comportamento standard come "non tornare indietro". Un interrupt è solo un modo di un thread che segnala qualcosa a un altro thread e questo può essere implementato per significare "quit" o non –

0

Viene generato uno InteruptedException quando un thread viene forzatamente interrotto. Questa non è una situazione usuale (cioè quando il thread è contesto disattivato dallo scheduler). Gli esempi potrebbero essere quando un altro thread manually interupts it o il processo riceve un segnale SIGINT.

+0

SIGKILL non interromperà i thread; li uccide direttamente, uccide l'intero processo JVM. –

+0

Mi dispiace, mio ​​male, intendevo 'SIGINT'. – SimonC

+0

SIGINT non chiamerà '.interrupt()' sui thread. Probabilmente eseguirà qualsiasi hook di arresto che hai aggiunto. Se interrompe i thread, potrebbe causare il caos: potrebbe essere necessario terminare i thread in un ordine molto specifico, in che modo la JVM dovrebbe conoscere l'ordine corretto? –