2010-04-21 23 views
5

Jusqu'à présent, j'ai utilisé mon application en tant que produit autonome. Donc, lorsque l'utilisateur a appuyé sur le bouton "Stop" j'ai appelé System.exit(0); et c'était bien.Comment puis-je fermer mon logiciel en toute sécurité?

Maintenant, mon application sera appelée (d'une manière programmatique) à partir d'un autre programme. Donc, j'ai peur que System.exit(0); ne tue non seulement mon processus mais aussi le logiciel externe qui a démarré mon programme. Alors, quelle est la bonne façon d'arrêter mon application si une demande correspondante d'un logiciel externe est reçue? Mon application est une application graphique. Donc, je veux fermer la fenêtre mais je veux aussi fermer tous les processus effectués par mon programme.

AJOUTÉE:

Pour être plus précis, je veux fermer toutes les discussions ouvertes par mon programme. Mon programme ne démarre aucun processus de système d'exploitation ou tout autre programme.

+0

@Roman: par * "processus exécutés par mon programme" * voulez-vous dire tous les threads que votre programme Java exécute ou votre programme a engendré, disons, d'autres exécutables (processus shell Un * x, .exe, autres Programme Java en cours d'exécution dans leur machine virtuelle, quel que soit)? – SyntaxT3rr0r

+0

@WizardOfOdds, je veux dire "tous les threads mon programme Java est en cours d'exécution". – Roman

+1

Comment votre programme est-il appelé? Est-ce qu'une certaine méthode est appelée par un programme Java déjà en cours d'exécution, si bien que les deux deviennent un programme? Ou l'autre programme lance-t-il un appel système pour démarrer une nouvelle machine virtuelle Java avec votre programme? –

Répondre

0

Tant que votre programme ne partage pas un serveur d'applications avec d'autres, l'arrêt de la machine virtuelle en appelant System.exit(0) met fin à tous les threads.

De Javadoc System.exit Met fin à la cours d'exécution Java Virtual Machine)

EDIT: Si vous voulez faire un peu de nettoyage le code avant l'arrêt, http://java.sun.com/j2se/1.4.2/docs/guide/lang/hook-design.html

+0

@stacker, voulez-vous dire que 'System.exit (0)' fermera tous les threads, y compris le thread du logiciel externe (qui a démarré mon programme). – Roman

+1

Il va tuer la JVM. Donc, si le logiciel externe a démarré votre programme en générant un processus Java, tout ira bien. Si le logiciel externe est un code Java qui crée simplement une instance de votre classe (s) et les exécute, ce code externe sera également tué. –

2

Si les fils que vous avez lancé sont le traitement en cours, puis en appelant System.exit (0) provoquera leur destruction. Dans certains cas, cela peut laisser votre application dans un état incohérent. Imaginez que le fil enregistrait un fichier par exemple.

Vous devez vous assurer que vos threads sont tous «heureux» de mourir avant d'appeler System.exit.

Une technique que vous pouvez utiliser pour cela avec des threads longs est l'empoisonnement. Pour ce faire, vous envoyez un message aux threads, à savoir qu'ils doivent maintenant mourir avec grâce, c'est-à-dire un message poson. Une fois qu'ils sont tous morts, il est prudent d'appeler System.exit (0) pour terminer le thread de gestion des événements Swing.

Il existe de nombreuses façons d'implémenter l'empoisonnement, vous pouvez simplement définir une variable d'indicateur global que les threads vérifient s'ils ont été empoisonnés, ou vous pouvez utiliser les bibliothèques de threads Java 5. Jetez un oeil à ce Javadoc par exemple, et vous trouverez des références à cette technique:

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

0

Il est sur « one-size-fits-all » réponse à ce qui est une solution de remplacement pour le système .exit, malheureusement.

Vous aurez généralement besoin de définir un type de drapeau qui signale à tous vos threads qu'il est temps de quitter, et assurez-vous qu'ils vérifient régulièrement ce drapeau. Cela leur permettra de nettoyer gracieusement sans s'arrêter brusquement, et il garantit également que les effets sont limités à vos propres composants. Dans ce cas, le thread principal de votre application observerait également le drapeau, attendez que tous les threads de type "worker" se terminent et retourneraient ensuite tout le long de la pile jusqu'à ce que le point d'entrée de votre application soit atteint.

Cette question n'est pas trop différente des méthodes obsolètes Thread.stop (etc), en particulier en ce qui concerne le remplacement de System.exit avec quelque chose de plus respectueux. Dans cette optique, le why is Thread.stop() deprecated page peut être une lecture utile.Lancer une exception (une exception personnalisée appelée quelque chose comme ApplicationStopException) pour dérouler la pile du thread principal n'est pas une si mauvaise idée; Cela vous évite d'avoir à gérer la logique spéciale partout dans votre code et laisse le "message" se propager aux niveaux supérieurs, où ils peuvent prendre toutes les mesures nécessaires pour quitter votre programme avec élégance.

0

Je vous recommande de faire un signal pour arrêter le fil afin que le fil sache quand il doit s'arrêter. Pour l'interface graphique et la fenêtre, vous pouvez appeler frame.dispose(). Pour System.exit(), je pense que cela n'affectera pas l'appelant, vous pouvez essayer de voir quel est l'effet réel mais comme d'autres personnes déjà recommandé, ne l'appelez pas directement comme ça, laissez les threads s'arrêter par lui-même