2010-10-23 7 views
15

Subj. Comment exécuter thread de la classe principale BUT séparément de cette classe?Java: Comment exécuter le thread séparément du programme principal/de la classe?

Donc un peu de détails: J'ai un programme qui doit exécuter un processus. Ce processus (un cmd) ne s'exécute que lorsque le programme principal est terminé et déchargé de la mémoire. Et seulement après décharger le programme principal ce processus commençant son travail.

Que devrais-je ajouter au programme?

+0

Je sais que c'est en retard, mais avez-vous jeté un oeil à ['ProcessBuilder'] (http://docs.oracle.com/javase/8/docs/api/java/lang/ProcessBuilder.html) en tant que option différente? – mkobit

Répondre

30

Si vous voulez dire: comment puis-je démarrer un thread Java qui ne se terminera pas lorsque ma JVM (programme java) le fera?.

The answer is: you can't do that.

Comme en Java, si la machine virtuelle Java sort, toutes les discussions sont faites. Voici un exemple:

class MyRunnable implements Runnable { 
    public void run() { 
     while (true) { 
      doThisVeryImportantThing(); 
     } 
    } 
} 

Le programme ci-dessus peut être démarré à partir de votre thread principal, par exemple, ce code:

MyRunnable myRunnable = new MyRunnable(); 
Thread myThread = new Thread(myRunnable); 
myThread.start(); 

Cet exemple programme ne sera jamais arrêter, à moins que quelque chose dans doThisVeryImportantThing prendra fin ce fil. Vous pouvez l'exécuter comme un démon, comme dans cet exemple:

MyRunnable myRunnable = new MyRunnable(); 
Thread myThread = new Thread(myRunnable); 
myThread.setDaemon(true); // important, otherwise JVM does not exit at end of main() 
myThread.start(); 

Cela fera en sorte, si le thread principal() se termine, il sera également fin MyThread.

Vous pouvez cependant commencer une autre machine virtuelle Java à partir de Java, pour que vous pourriez vouloir vérifier cette question: Launch JVM process from a Java application use Runtime.exec?

+1

Après l'appel de myThread.start(), qu'advient-il de myRunnable? Peut-on encore interagir avec lui comme d'habitude (par exemple des méthodes d'appel en dehors de run())? – aednichols

0

Semble que vous voulez un script qui appelle le premier programme, puis lorsque le premier se termine, il appelle le deuxième programme.

Quelque chose comme

program1 
program2 

EDIT: Pour exécuter les deux tâches en parallèle, vous pouvez faire

program1 & 
program2 

dans une coquille bash/unité.

ou dos coquille

start program1 
program2 
+0

En fait non. J'ai classe principale qui me fait 1 processus et ce processus ne devrait pas bloquer le programme principal (ce que je pensais) et doit faire son travail séparément de la classe principale. – helpmepls

+0

Vous avez déclaré que vous avez besoin de "Ce processus (un cmd) ne s'exécute que lorsque le programme principal est terminé et déchargé de la mémoire". L'utilisation de Runtime.exec() démarre le deuxième processus avant que le premier ne soit terminé et avant qu'il ne soit déchargé. –

+0

Vous dernier commentaire suggère que vous voulez que les deux processus à exécuter en même temps. –

0

Je ne suis pas tout à fait sûr que vous pouvez faire un fil PAVILLON 'en Java en utilisant les moyens normaux de la mise en œuvre de cette discussion et coups de pied hors de course().

Il se peut que vous deviez insérer un fil à l'aide de Runtime.exec(), en exécutant java comme un processus entièrement distinct et non comme un fil.

+0

J'utilise Runtime.exec() pour lancer le processus, mais ce processus ne commencera pas à fonctionner (mais il est en UP et en quelque sorte suspendu) jusqu'à ce que mon programme principal ne soit pas abandonné. – helpmepls

+0

Si vous utilisez un * nix, je crois que vous pouvez détacher le processus en plaçant une esperluette derrière la commande: 'top &' –

+0

Malheureusement j'utilise Windows. – helpmepls

0

Pour lancer un processus qui survit après la JVM vous termine aurez besoin d'utiliser Runtime.exec() .Puisque vous le souhaitez courir après votre processus principal se termine, il y a vraiment deux façons dont vous pouvez le faire:

1) Si vous voulez seulement traiter de fonctionner lors d'un arrêt propre alors vous pouvez faire ceci:

public static void main(String[] args) { 
    doThisProgramsStuff(); 
    spawnSecondProcess(); 
} 

2) ou, si vous voulez que le processus de fonctionner même avec un arrêt impur (ou si elle est une application GUI) vous pouvez ajouter un crochet d'arrêt:

public static void main(String[] args) { 
    Runtime.getRuntime().addShutdownHook(new Thread() { 
     public void run() { 
      spawnSecondProcess(); 
     } 
    }); 
    doThisProgramsStuff(); 
} 

il y a, cependant, un problème tout ça. Une fois que la JVM se termine, le processus enfant aura une entrée/sortie standard attachée à rien, de sorte qu'il pourrait remplir ses tampons de sortie et bloquer. Vous devrez faire quelque chose pour vous assurer que cela n'arrive pas en s'assurant que le processus ne produit pas de sortie pour ces flux ou en faisant l'équivalent Windows de la redirection vers/dev/null.

4

Créer un thread séparé qui exécute votre programme externe:

class MyRunner implements Runnable{ 
    public void run(){ 
    Runtime.exec("your cmd") 
    } 
} 

puis lancez le fil dans votre main():

MyRunner myRunner = new MyRunner(); 
Thread myThread = new Thread(myRunner); 
myThread.start(); 

De cette façon, votre programme principal continuera à fonctionner, tandis que l'arrière-plan thread démarrera un processus externe et quittera lorsque ce programme se termine.

+0

Merci pour cette réponse! – helpmepls