Introducción al estado de subprocesos de Java con ejemplo: ciclo de vida de un subproceso
Publicado: 2019-01-11
Estados de subprocesos
El siguiente diagrama ilustra los diversos estados en los que puede encontrarse un subproceso de Java en cualquier momento de su vida y qué llamadas a métodos provocan una transición a otro estado. Este diagrama no es un diagrama de estado finito completo, sino una descripción general de las facetas más interesantes y comunes de la vida de un subproceso.
Está en el lugar correcto si tiene alguna de las siguientes preguntas:
- Ciclo de vida de un hilo en Java
- Ciclo de vida y estados de un hilo en Java
- Comprensión de los estados de subprocesos de Java
El resto de esta página analiza Thread's life cycle
en términos de su estado.

Nuevo hilo
La siguiente declaración crea un nuevo subproceso pero no lo inicia, por lo que deja el subproceso en el estado etiquetado como Nuevo subproceso en el diagrama.
1 |
Thread myThread = new MyThreadClass ( ) ; |
Cuando un subproceso está en el estado New Thread
, es simplemente un objeto Subproceso vacío. Aún no se han asignado recursos del sistema para ello. Por lo tanto, cuando un subproceso está en este estado, solo puede iniciar el subproceso o detenerlo; llamar a cualquier otro método además de start()
o stop()
cuando un subproceso está en este estado no tiene sentido y provoca una IllegalThreadStateException.
Ejecutable
Ahora considere estas dos líneas de código:
1 2 |
Thread myThread = new MyThreadClass ( ) ; myThread . start ( ) ; |
El método start()
crea los recursos del sistema necesarios para ejecutar el subproceso, programa la ejecución del subproceso y llama al método run()
del subproceso. En este punto, el subproceso se encuentra en el estado "Ejecutable". Este estado se denomina "Ejecutable" en lugar de "En ejecución" porque es posible que el subproceso no se esté ejecutando cuando se encuentra en este estado. Muchas computadoras tienen un solo procesador, lo que hace imposible ejecutar todos los subprocesos "ejecutables" al mismo tiempo.
Por lo tanto, el sistema de tiempo de ejecución de Java debe implementar un esquema de programación que comparta el procesador entre todos los subprocesos "ejecutables". Sin embargo, para la mayoría de los propósitos, puede pensar en el estado "Ejecutable" como simplemente "En ejecución". Cuando un subproceso se está ejecutando, es "Ejecutable" y es el subproceso actual, las instrucciones en su run()
se ejecutan secuencialmente.
no ejecutable
Un subproceso entra en el estado Not Runnable
cuando ocurre uno de estos cuatro eventos:
- alguien llama a su método
suspend()
- alguien llama a su método
sleep()
- el hilo usa su método
wait()
para esperar en una variable de condición - el hilo está bloqueando en I/O.
Por ejemplo, la línea en negrita en este fragmento de código
1 2 3 4 5 6 |
Thread myThread = new MyThreadClass ( ) ; myThread . start ( ) ; try { myThread . sleep ( 10000 ) ; } catch ( InterruptedException e ) { } |
pone myThread
en reposo durante 10 segundos (10.000 milisegundos). Durante esos 10 segundos, incluso si el procesador estuviera disponible, myThread
no se ejecutaría. Después de que transcurran los 10 segundos, myThread
vuelve a ser "Ejecutable" y ahora, si el procesador estuviera disponible, myThread
se ejecutaría.
Para cada una de las "entradas" al estado "No ejecutable" mencionado anteriormente, hay una ruta de escape específica y distinta que devuelve el subproceso al estado "Ejecutable". Una vía de escape sólo sirve para su correspondiente “entrada”. Por ejemplo, si un subproceso se ha puesto en suspensión, debe transcurrir el número especificado de milisegundos antes de que el subproceso vuelva a ser "Ejecutable". Llamar resume()
en un subproceso inactivo no tiene ningún efecto.
A continuación se indica la ruta de escape para cada entrada al estado "No ejecutable".

- Si un subproceso se ha puesto a dormir, entonces debe transcurrir el número especificado de milisegundos.
- Si un hilo ha sido suspendido, entonces alguien debe llamar a su método
resume()
. - Si un subproceso está esperando una variable de condición, cualquier objeto que posea la variable debe renunciar a ella llamando a
notify()
o notificar anotifyAll()
. - Si un subproceso está bloqueado en E/S, entonces el comando de E/S especificado debe completarse.

Muerto
Un subproceso puede morir de dos maneras: ya sea por causas naturales o por ser eliminado (detenido). Un hilo muere naturalmente cuando su método run()
sale normalmente. Por ejemplo, el ciclo while
en este método es un ciclo finito: iterará 100 veces y luego saldrá.
1 2 3 4 5 6 7 |
public void run ( ) { int i = 0 ; while ( i < 100 ) { i ++ ; System . out . println ( "i = " + i ) ; } } |
Un subproceso con este método run()
morirá naturalmente después de que se complete el bucle y el método run()
.
También puede cerrar un hilo en cualquier momento llamando a su método stop()
. Este fragmento de código.
1 2 3 4 5 6 7 |
Thread myThread = new MyThreadClass ( ) ; myThread . start ( ) ; try { Thread . currentThread ( ) . sleep ( 10000 ) ; } catch ( InterruptedException e ) { } myThread . stop ( ) ; |
crea e inicia myThread
y luego pone el hilo actual en reposo durante 10 segundos. Cuando el subproceso actual se activa, la línea en negrita en el segmento de código elimina myThread
.
El método stop()
lanza un objeto ThreadDeath al hilo para matarlo. Por lo tanto, cuando se mata un subproceso de esta manera, muere de forma asíncrona. El subproceso morirá cuando realmente reciba la excepción ThreadDeath.
IllegalThreadStateExceptionIlegalThreadStateException
El sistema de tiempo de ejecución lanza una excepción IllegalThreadStateException cuando llama a un método en un subproceso y el estado de ese subproceso no permite la llamada a ese método. Por ejemplo, IllegalThreadStateException se lanza cuando llamas a suspend suspend()
en un subproceso que no es "Ejecutable".
Como se muestra en los diversos ejemplos de subprocesos hasta ahora en esta lección, cuando llama a un método de subproceso que puede generar una excepción, debe capturar y manejar la excepción, o declarar que el método de llamada genera la excepción no detectada.
El método isAlive()
Y una palabra final sobre el estado del hilo: la interfaz de programación para la clase Thread incluye un método llamado isAlive()
. isAlive()
devuelve verdadero si el subproceso se inició y no se detuvo. Por lo tanto, si el método isAlive()
devuelve falso , sabrá que el subproceso es un "Nuevo subproceso" o "Muerto".
Si el método isAlive()
devuelve verdadero , sabrá que el subproceso es "Ejecutable" o "No ejecutable". No puede diferenciar entre un "Nuevo hilo" y un hilo "Muerto"; ni puede diferenciar entre un subproceso "Ejecutable" y un subproceso "No ejecutable".
Mientras miraba ejemplos complejos de subprocesos, encontré este tutorial realmente excelente en la red. Todo el mundo debería leer esto detenidamente.