2010-04-21 6 views
5

Fino ad ora ho utilizzato la mia applicazione come prodotto indipendente. Quindi, quando l'utente ha premuto il tasto "Stop" ho chiamato System.exit(0); e andava bene.Come posso chiudere il mio software in modo sicuro?

Ora la mia applicazione verrà chiamata (in modo programmatico) da un altro programma. Quindi, temo che lo System.exit(0); uccida non solo il mio processo ma anche il software esterno che ha avviato il mio programma.

Quindi, qual è il modo corretto di arrestare la mia applicazione se viene ricevuta una richiesta corrispondente da un software esterno? La mia applicazione è un'applicazione GUI. Quindi, voglio chiudere la finestra ma voglio anche chiudere tutti i processi eseguiti dal mio programma.

aggiunto:

Per essere più precisi, voglio chiudere tutte le discussioni iniziate da mio programma. Il mio programma non avvia alcun processo del sistema operativo o qualsiasi altro programma.

+0

@Roman: da * "processi eseguiti dal mio programma" * intendi tutti i thread del programma Java in esecuzione o il tuo programma ha generato, ad esempio, altri eseguibili (processi shell Un * x, .exe, altro Programma Java in esecuzione nella loro VM, qualunque cosa)? – SyntaxT3rr0r

+0

@WizardOfOdds, intendo "tutti i thread il mio programma Java è in esecuzione". – Roman

+1

Come viene richiamato il tuo programma? Un certo metodo viene chiamato da un programma Java già in esecuzione, quindi i due diventano un unico programma? Oppure l'altro programma sta effettuando una chiamata di sistema per avviare una nuova VM Java con il tuo programma? –

risposta

0

Fintantoché il programma non condivide un server applicazioni con altri, arrestare la VM chiamando System.exit(0) termina tutti i thread.

Da Javadoc System.exit Termina l'attualmente in esecuzione Java Virtual Machine)

EDIT: Se si vuole fare un po 'ripulire il codice prima dell'arresto, http://java.sun.com/j2se/1.4.2/docs/guide/lang/hook-design.html

+0

@stacker, vuoi dire che 'System.exit (0)' chiuderà tutti i thread in basso incluso il thread del software esterno (che ha avviato il mio programma). – Roman

+1

Ucciderà la JVM. Quindi, se il software esterno ha avviato il programma creando un processo Java, andrà bene. Se il software esterno è un codice Java che crea semplicemente un'istanza della classe (es) e le esegue, allora anche quel codice esterno verrà ucciso. –

2

Se i fili che avete lanciato sono l'elaborazione continua quindi chiamando System.exit (0) causerà la loro eliminazione. In alcuni casi, questo può lasciare l'applicazione in uno stato incoerente. Immagina che il thread stesse salvando un file, per esempio.

È necessario assicurarsi che i thread siano tutti "felici" di morire prima di chiamare System.exit.

Una tecnica che è possibile utilizzare per questo con thread a lungo termine è l'avvelenamento. Per fare ciò inviate ai thread un messaggio che dovrebbero ora morire con grazia - cioè un messaggio poson. Una volta che tutti sono morti, è possibile chiamare System.exit (0) per terminare il thread di gestione degli eventi di Swing.

Esiste un sacco di modi diversi per implementare l'avvelenamento, basta impostare una variabile di flag globale che i thread controllino per vedere se sono stati avvelenati, oppure è possibile utilizzare le librerie di threading di Java 5. Date un'occhiata a questo Javadoc per esempio, e troverete i riferimenti a questa tecnica:

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html

0

C'è il "one-size-fits-all" risposta a questo che è un rimpiazzo per il sistema .exit, sfortunatamente.

Generalmente è necessario impostare un tipo di flag che segnali a tutti i thread che è ora di uscire e assicurarsi di controllare questo flag regolarmente. Questo permetterà loro di pulire con grazia senza fermarsi bruscamente, e garantisce anche che gli effetti siano limitati ai propri componenti. In questo caso, il thread principale della tua applicazione dovrebbe osservare anche il flag, attendere che tutti i thread del tipo "worker" finiscano e tornare indietro nello stack fino al raggiungimento del punto di ingresso dell'applicazione.

Questa domanda non è troppo dissimile dai metodi deprecati di Thread.stop (ecc.), In particolare per quanto riguarda la sostituzione di System.exit con qualcosa di più rispettoso. In questa luce, il why is Thread.stop() deprecated page potrebbe essere utile per la lettura.

Lanciare un'eccezione (una personalizzata chiamata qualcosa come ApplicationStopException) per lo svolgimento della pila del thread principale non è una cattiva idea; questo ti impedisce di dover gestire la logica speciale su tutto il tuo codice e invece permette al "messaggio" di propagarsi ai livelli più alti, dove possono prendere qualsiasi azione necessaria per uscire con grazia dal tuo programma.

0

vi consiglio di fare segnalazione per fermare il filo in modo che il filo si sa quando si deve fermare. Per la GUI e la finestra, puoi chiamare frame.dispose().

Per System.exit(), penso che non influirà sul chiamante, potresti provare a vedere qual è l'effetto reale ma, come altre persone già consigliato, non chiamarlo direttamente in questo modo, lascia che i thread si fermino da solo