2015-07-06 37 views
7

Sto leggendo i documenti sul metodo Java setDaemon() e mi sono confuso quando ho letto che JVM si chiude senza attendere il completamento dei thread daemon.Come sopravvive il thread daemon dopo la chiusura di JVM?

Tuttavia, dal momento che essenzialmente i thread daemon sono Java Thread, che presumibilmente si basano sull'esecuzione su JVM per raggiungere le sue funzionalità, in che modo i thread daemon sopravvivono anche se JVM termina prima del completamento del thread daemon?

+0

Stai solo fraintendendo cosa vuol dire _attendere i thread daemon per finire_. Fine significa completare l'esecuzione del metodo 'run' di Runnable'. –

+0

Dove dice che sopravvivono? La tua domanda non ha senso, – EJP

risposta

15

Non sopravvivono. La JVM uscirà quando tutti i thread, tranne quelli daemon, sono morti.

Quando si avvia l'applicazione, la JVM avvierà un singolo thread non demone per eseguire il metodo principale statico.

Una volta terminato il metodo principale, questo thread principale morirà e se non si generano altri thread non daemon, la JVM uscirà.

Se tuttavia è stato avviato un altro thread, la JVM non uscirà, attenderà che tutti i thread non daemon muoiano prima di uscire.

Se quel thread generato genera qualcosa di vitale, questa è assolutamente la cosa giusta da fare, tuttavia spesso si hanno dei thread che non sono così importanti, forse stanno ascoltando alcuni eventi esterni che potrebbero o meno accadere.

Quindi, in teoria, è necessario posizionare un codice da qualche parte per interrompere tutti i thread generati per consentire l'uscita dalla JVM.

Poiché questo è soggetto a errori, è molto più semplice contrassegnare tali thread non vitali come daemon. Se sono contrassegnati come tali, la JVM non aspetterà che muoiano prima di uscire, la JVM uscirà e ucciderà quei thread quando i "thread principali" (quelli non contrassegnati come demone) sono morti.

Per dirla in codice, è qualcosa di simile:

public class Spawner { 
    public static void main(String[] args) { 
    Thread t = new Thread(new Runnable() { 
     public void run() { 
     while (true) { 
      System.out.println("I'm still alive"); 
     } 
     } 
    }); 
    t.start(); 
    // Try uncommenting/commenting this line 
    // t.setDaemon(true); 
    System.out.println("Main thread has finished"); 
    } 
} 

(non ho ancora testato questo codice, ha scritto qui direttamente, in modo che possa contenere errori stupidi).

Quando si esegue questo codice con la riga commentata, il thread non è deamon, quindi anche se il metodo principale ha finito, si continuerà ad avere la console inondata fino a quando non la si interrompe con CTRL + C. Cioè, la JVM non uscirà.

Se si decommenta la riga, il thread è un daemon e poco dopo il termine del metodo principale, il thread verrà ucciso e la JVM verrà chiusa senza la necessità di CTRL + C.

+0

Cosa succede se voglio un ascoltatore su qualche porta per catturare determinati eventi? Sembra che l'ascoltatore verrà ucciso quando uscirà JVM, quindi perderò semplicemente il mio ascoltatore? – OneZero

+0

Sì, se la JVM esiste, il tuo programma è finito, tutte le risorse vengono liberate, quindi non stai più ascoltando su nessuna porta. –

+0

però è più una domanda di programmazione di sistema. in pratica, cosa fa il sistema operativo all'uscita del processo. non è specifico di java. – the8472

2

Il demone non sopravvivrà se JVM esce.

Che si tratti di un daemon o meno, un thread Java viene eseguito su una macchina virtuale Java. Se la macchina virtuale muore, ogni thread Java in esecuzione su di esso muore con esso, inclusi i thread daemon.

Il thread daemon in Java è il thread che viene eseguito in background e principalmente creato da JVM per eseguire attività in background come Garbage Collection e altre attività di housekeeping.

Non appena il programma java di esecuzione del completamento del thread utente o JVM si termina, JVM non attende il thread daemon per terminare l'esecuzione. Non appena termina l'ultimo thread non demone, JVM termina indipendentemente dal numero di thread Daemon esistente o in esecuzione all'interno di JVM.

Nota: I thread daemon non vengono interrotti in chiusura, né i loro metodi finalize() vengono necessariamente richiamati.

È sempre possibile aggiungere un gancio di arresto alla JVM Durata:

Thread shutdownHook = ... // construct a thread that performs graceful 
          // shutdown of JVM 
Runtime.getRuntime().addShutdownHook(shutdownHook); 

gancio di arresto può fare shutdown di un thread demone secondo il vostro bisogno.