2010-10-23 13 views
15

Subj. Cómo ejecutar el hilo desde la clase principal PERO por separado de esa clase?Java: ¿Cómo ejecutar el hilo por separado desde el programa/clase principal?

Así que un poco de detalles: Tengo un programa que debe ejecutar un proceso. Ese proceso (un cmd) se ejecuta solo cuando el programa principal finaliza y se descarga de la memoria. Y solo después de descargar el programa principal que procesa comenzar su trabajo.

¿Qué debo agregar al programa?

+0

Sé que es tarde, pero echó un vistazo a ['ProcessBuilder'] (http://docs.oracle.com/javase/8/docs/api/java/lang/ProcessBuilder.html) como un opción diferente? – mkobit

Respuesta

30

Si quiere decir: ¿cómo puedo iniciar un hilo de Java que no terminará cuando lo haga mi JVM (programa de Java)?.

The answer is: you can't do that.

Debido a que en Java, si la JVM sale, todas las discusiones se llevan a cabo. Este es un ejemplo:

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

El programa anterior se puede iniciar desde el hilo principal, por ejemplo, este código:

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

Este programa de ejemplo que nunca se detendrá, a menos que algo en doThisVeryImportantThing terminará ese hilo. Usted podría funcionar como un demonio, como en este ejemplo:

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

Esto se asegurará de que, si termina el() hilo principal, sino que también terminará miThread.

Sin embargo, puede iniciar una JVM diferente de Java, por eso es posible que desee echa un vistazo a esta pregunta: Launch JVM process from a Java application use Runtime.exec?

+1

Después de invocar myThread.start(), ¿qué le sucede a myRunnable? ¿Todavía se puede interactuar con él como de costumbre (por ejemplo, llamar a métodos además de ejecutar())? – aednichols

0

Parece que desea una secuencia de comandos que llama al primer programa y luego, cuando el primero termina, llama al segundo programa.

Algo así como

program1 
program2 

EDIT: Para ejecutar las dos tareas en paralelo que puede hacer

program1 & 
program2 

en un shell bash/unidad.

o en el shell de DOS

start program1 
program2 
+0

En realidad no. Tengo la clase principal que me hace 1 proceso y ese proceso NO DEBE bloquear el programa principal (eso es lo que pensé) y debe hacer su trabajo por separado de la clase principal. – helpmepls

+0

Ha indicado que necesita "Ese proceso (un cmd uno) se ejecuta solo cuando el programa principal finalizó y se descargó de la memoria". El uso de Runtime.exec() inicia el segundo proceso antes de que termine el primero y antes de que se descargue. –

+0

Su último comentario sugiere que desea que los dos procesos se ejecuten al mismo tiempo. –

0

No estoy del todo seguro que puede hacer un hilo 'independiente' en Java utilizando los medios normales de la implementación de rosca y patadas con run().

Es posible que tenga que bifurcar un hilo usando Runtime.exec(), ejecutando Java como un proceso completamente separado, no como un hilo.

+0

Uso Runtime.exec() para ejecutar el proceso, pero ese proceso no comenzará a funcionar (pero está UP y tipo de suspensión o algo así) hasta que mi programa principal no se cierre. – helpmepls

+0

Si está ejecutando un * nix, creo que puede separar el proceso poniendo un símbolo comercial detrás del comando: 'top &' –

+0

Desafortunadamente utilizo Windows. – helpmepls

0

Para generar un proceso que sobrevive después de la JVM termina tendrá que utilizar Runtime.exec() .Puesto que desea que se ejecute después de que termine el proceso principal, en realidad hay dos maneras de hacerlo:

1) Si sólo desea procesar para funcionar durante un apagado limpio, entonces usted puede hacer esto:

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

2) o bien, si desea que el proceso se ejecute incluso con un cierre sucio (o si se trata de una aplicación de interfaz gráfica de usuario), entonces usted puede agregar un gancho de cierre:

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

Hay, sin embargo, un problema con todo esto. Una vez que termina la JVM, el proceso secundario tendrá una entrada/salida estándar sin conexión, por lo que podría llenar sus búferes de salida y bloquear. Tendrá que hacer algo para asegurarse de que esto no suceda ya sea asegurándose de que el proceso no produzca salida a esas transmisiones o haciendo el equivalente de Windows de redirigir a/dev/null.

4

Crear un hilo separado que ejecuta su programa externo:

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

a continuación, inicie el hilo en su main():

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

De esta manera el programa principal seguirá funcionando, mientras que su fondo thread iniciará un proceso externo y saldrá cuando este programa termine.

+0

¡Gracias por esa respuesta! – helpmepls

Cuestiones relacionadas