La siguiente sentencia crea un nuevo thread pero no lo arranca, por lo tanto deja el thread en el estado : "New Thread" = "Nuevo Thread".Thread miThread = new MiClaseThread();Cuando un thread está en este estado, es sólo un objeto Thread vacío. No se han asignado recursos del sistema todavía para el thread. Así, cuando un thread está en este estado, lo único que se puede hacer es arrancarlo o pararlo. Llamar a otros métodos distintos de start() o stop() no tiene sentido y causa una excepción del tipo IllegalThreadStateException.
Ahora consideremos estas dos líneas de código:Thread miThread = new MiClaseThread(); miThread.start();Cuando el método start() crea los recursos del sistema necesarios para ejecutar el thread, programa el thread para ejecutarse, y llama al método run() del thread. En este punto el thread está en el estado "Ejecutable". Este estado se llama "Ejecutable" mejor que "Ejecutando" ya que el thread todavía no ha empezado a ejecutarse cuando está en este estado. Muchos procesadores tienen un sólo procesador, haciendo posible que todos los threads sean "Ejecutables" al mismo tiempo. Por eso, el sistema de ejecución de Java debe implementar un esquema de programación para compartir el procesador entre todos los threads "Ejecutables". (Puedes ver la página Prioridad de un Thread para obtener más información sobre la programación.) Sin embargo, para la mayoría de los propositos puedes pensar en "Ejecutable" como un sencillo "Ejecutando". Cuando un thread se está ejecutanto -- está "Ejecutable" y es el thread actual -- las instrucciones de su método run()se ejecutan de forma secuencial.
Un thread entra en el estado "No Ejecutable" cuando ocurre uno de estos cuatro eventos:Por ejemplo, la línea en negrita del siguiente fragmento de codigo pone a dormir miThread durante 10 segundos (10.000 milisegundos):
- Alguien llama a su método sleep().
- Alguien llama a su método suspend().
- El thread utiliza su método wait() para esperar una condición variable.
- El thread está bloqueado durante la I/O.
Thread miThread = new MiClaseThread(); miThread.start(); try { miThread.sleep(10000); } catch (InterruptedException e){ }Durante los 10 segundos que miThread está dormido, incluso si el proceso se vuelve disponible miThread no se ejecuta. Después de 10 segundos, miThread se convierte en "Ejecutable" de nuevo y, si el procesar está disponible se ejecuta.Para cada entrada en el estado "No Ejecutable" mostrado en figura, existe una ruta de escape distinta y específica que devuelve el thread al estado "Ejecutable". Una ruta de escape sólo trabaja para su entrada correspondiente. Por ejemplo, si un thread ha sido puesto a dormir dutante un cierto número de milisegundos deben pasar esos milisegundos antes de volverse "Ejecutable" de nuevo. Llamar al método resume() en un thread dormido no tiene efecto.
Esta lista indica la ruta de escape para cada entrada en el estado "No Ejecutable":
- Si se ha puesto a dormir un thread, deben pasar el número de milisegundos especificados.
- Si se ha suspendido un thread, alguien debe llamar a su método resume().
- Si un thread está esperando una condición variable, siempre que el objeto propietario de la variable renuncie mediante notify() o notifyAll().
- Si un thread está bloqueado durante la I/O, cuando se complete la I/O.
Un thread puede morir de dos formas: por causas naturares o siendo asesinado (parado). Una muerte natural se produce cuando su método run() sale normalmente. Por ejemplo, el bucle while en este método es un bucle finito -- itera 100 veces y luego sale.public void run() { int i = 0; while (i < 100) { i++; System.out.println("i = " + i); } }Un thread con este método run() moriría natualmente después de que el bucle y el método run() se hubieran completado.También puede matar un thread en cualquier momento llamando a su método stop(). El siguiente código crea y arranca miThread luego lo pone a dormir durante 10 segundos. Cuando el thread actual se despierta, la línea en negrita mata miThread.
Thread miThread = new MiClaseThread(); miThread.start(); try { Thread.currentThread().sleep(10000); } catch (InterruptedException e){ }miThread.stop();El método stop() lanza un objeto ThreadDeath hacia al thread a eliminar. Así, cuando se mata al thread de esta forma, muere de forma asíncrona. El thread moririá cuando reciba realmente la excepción ThreadDeath.El método stop() provoca una terminación súbita del método run() del thread. Si el método run() estuviera realizando cálculos sensibles, stop() podría dejar el programa en un estado inconsistente. Normalmente, no se debería llamar al método stop() pero si se debería proporcionar una terminación educada como la selección de una bandera que indique que el método run() debería salir.
El sistema de ejecución lanza una excepción IllegalThreadStateException cuando llama a un método en un thread y el estado del thread no pemmite esa llamada a método. Por ejemplo, esta excepción se lanza cuando se llama a suspend() en un thread que no está "Ejecutable".Como se ha mostrado en varios ejemplos de threads en está lección, cuando se llame a un método de un thread que pueda lanzar una excepción, se debe capturar y manejar la excepción, o especificar al método llamador que se lanza la excepción no capturada. Puedes ver la información sobre el manejo de excepciones en Java en Excepciones
Una última palabra sobre el estrado del thread: el interface de programación de la clase Thread incluye un método llamado isAlive(). Este método devuelve true si el thread ha sido arrancado y no ha parado. Así, si el método isAlive() devuelve false sabrás que se trata de un "Nuevo thread" o de un thread "Muerto". Por el contrario si devuelve true sabrás que el thread esá "Ejecutable" o "No Ejecutable". No se puede diferenciar entre un "Nuevo thread" y un thread "Muerto", como tampoco se puede hacer entre un thread "Ejecutable" y otro "No Ejecutable"