2012-03-11 31 views
7

¿saldrá el hilo principal antes de que los hilos secundarios completen la ejecución?¿saldrá el hilo principal antes de que los hilos secundarios completen la ejecución?

leí en 2 artículos

http://www.cs.mtu.edu/~shene/NSF-3/e-Book/FUNDAMENTALS/thread-management.html

en el artículo anterior, En "Terminación del hilo" para, se afirma en Red "si el hilo padre termina, todos los subprocesos niño terminan así. "

http://www.roseindia.net/java/thread/overview-of-thread.shtml

en el artículo anterior, la última línea de esa página estados "The) ejecución principal (método puede terminar, pero el programa sigue funcionando hasta que los temas tienen completar su ejecución.".

i tarifa son contradictorias. si estoy equivocado, por favor los expertos me corrigen.

En mi programa, un programa con método principal llama al constructor de 2 hilos. en el constructor de los hilos respectivos, estoy teniendo el método start().

 TestA A = new TestA("TestA"); 
    TestB B = new TestB("TestB"); 

    public TestA(String name) { 
    System.out.println(name); 
    t = new Thread(this); 
    t.start(); 
} 

me gustaría saber lo que pasa, hilo principal termina antes de hilos de ejecución completa del niño? si es así, ¿el niño entablará conversación de todos modos, continuará su ejecución?

intenté ejecutar el programa, algunas veces todos los subprocesos hijo se ejecutan completos incluso si el hilo principal se cierra. En los 2 hilos, estoy procesando algunos archivos. en el hilo A de testA, solo 1 archivo no se procesa algunas veces. pero muchas veces, todos los archivos se están procesando y no tengo ningún problema.

Respuesta

20

Java hace una distinción entre un subproceso de usuario y otro tipo de subproceso conocido como subproceso de daemon. La diferencia entre estos dos tipos de subprocesos es que si la JVM determina que los únicos subprocesos que se ejecutan en una aplicación son subprocesos de daemon (es decir, no hay subprocesos de usuario), el tiempo de ejecución de Java cierra la aplicación. Por otro lado, si al menos un subproceso de usuario está activo, el tiempo de ejecución de Java no terminará su aplicación.

Cuando su método main() recibe inicialmente el control del tiempo de ejecución de Java, se ejecuta en el contexto de un hilo de usuario. Siempre que el hilo del método principal o cualquier otro hilo de usuario permanezca activo, su aplicación continuará ejecutándose.

En su caso, los hilos son hilos de usuario y, por lo tanto, pueden completarse antes de que salga el hilo principal.

Estoy procesando algunos archivos. en el hilo A de testA solo, 1 solo archivo es que no se procesa algunas veces. pero muchas veces

El motivo de lo anterior puede deberse a algo más que las salidas de hilo. Podría ser bloqueos de archivos, etc. problema de sincronización

De Java Thread API documentation:

Cuando una máquina virtual Java se pone en marcha, por lo general hay una sola rosca no-daemon (que normalmente llama el método llamado principal de alguna clase designada ).La Máquina Virtual de Java continúa ejecutando hilos hasta que cualquiera de las siguientes situaciones:

La salida del método de tiempo de ejecución de clase ha sido llamado y la seguridad gerente ha permitido la operación de salida se produzca. Todos los subprocesos que no son subprocesos de daemon han muerto, ya sea al regresar de la llamada al método de ejecución o al lanzar una excepción que propaga más allá del método de ejecución.

+0

Gracias por la explicación detallada. mencionó que "en su caso, los hilos son hilos de usuario y, por lo tanto, pueden completarse antes de que salga el hilo principal". Aquí quiere decir "hilo principal" para ser el tiempo de ejecución de Java, no el programa con el método principal(). ¿correcto? – user1257836

+0

la clase que tiene el método principal y los hilos que se crean dentro del método principal son todos hilos de usuario. todos estos hilos son independientes se ejecutan al mismo tiempo. Porque di System.out.println ("exit of main method"); al final del método principal. esto se imprime antes que system.out.println() en los hilos hijo. esto me hizo pensar que el hilo principal (clase que tiene el método principal) puede salir incluso antes de que el hijo se enrosque. ¿Es esta forma correcta y correcta de comportamiento? – user1257836

+0

¿puede aclarar qué quiere decir con bloqueos de archivos? ¡¡gracias por adelantado!! – user1257836

2

Una vez que sale el hilo principal, lleva a los niños con él. Tal vez por "finalizar" el segundo artículo simplemente significa no más operación que esperar a los niños. Una vez que el hilo principal llama a System.exit (0); se acabó - cada cuerpo muere.

Supongamos que tiene dos hilos en ejecución: threadA y threadB. en el método principal. El primer código es la buena manera de terminar el hilo - sólo una de muchas formas:

threadA.start(); 
threadB.start(); 
final long intercept = 300; 
long startTime = System.currentTimeMillis(); 
while (threadA.isAlive() && mis.isAlive()) { 
    threadA.join(intercept); 
if (System.currentTimeMillis() - startTime > intercept) { 
    threadB.interrupt(); 
    threadA.interrupt(); 
    threadA.join(); 
} 
} 
System.exit(0); 

A continuación se muestra una forma abrupta de matar todas las discusiones desde dentro principal:

System.exit(0); 
+0

Gracias por la respuesta. Nunca utilicé System.exit (0) en mi programa. "Una vez que sale el hilo principal, lleva a los niños con él" .am todavía no está claro. el programa que tiene el método principal crea 2 hilos y se completa.pero los hilos secundarios que se engendraron continuarán, ¿no es así? – user1257836

3

Los hilos de fondo se sigue corriendo, incluso si el hilo PRINCIPAL se completa.

Si desea que MAIN los detenga (por ejemplo, cuando MAIN está completo), haga que su MAIN configure una variable de indicador "keep running" (que debe establecer como "volátil"), que los subprocesos ocasionalmente miran. MAIN lo establece en falso (variable) o nulo (objeto) cuando MAIN quiere detenerlos. Cuando es falso o nulo, el hilo debe "regresar".

Esto es algo complejo de implementar, hay muchas formas, pero lo más fácil es hacer que Runnable sea una clase interna, para que Runnable pueda compartir fácilmente la bandera.

Para las mejores implementaciones, busque esta técnica en las rutinas de inicio/detención de los applets de Java.

Cuestiones relacionadas