Programação com Threads Threads Java como um Estudo de Caso
Estados de uma Thread Java O diagrama seguinte mostra os estados nos quais uma thread Java pode estar e alguns métodos que podem ser usados para mudar de um estado para outro.
Ciclo de Vida de Java Threads Nova Dormindo Pronta Terminado Em Espera Executando Bloqueada Morto
Nova Thread - NEW Inicialização da thread – Feita através do construtor Thread(). class MyThreadClass extends Thread{ ... } ... MyThreadClass myThread = new MyThreadClass();
NEW RUNNABLE (Executável) Neste estado de NEW (Nova), nenhum recurso do sistema foi alocado para a thread, ainda. Assim, a partir daqui, tudo que você pode fazer é um start()para ativar a thread, e a thread passa a um estado RUNNANLE (estado Ready), ou um stop(), para "matá-lo". A chamada de qualquer outro método não faz sentido e levantará a exceção IllegalThreadStateException.
Estado de RUNNABLE (Pronto) Quando uma thread entra pela primeira vez no estado RUNNABLE a partir do estado “NEW”, ela vai para o estado de “Ready”, que a JVM não vê. Este é o estado em que o thread está pronta para rodar, mas não tem os recursos do SO para ser executada. O método start()requisita os recursos do SO, necessários para rodar a thread e chama o seu método run(). O método run() é a "alma" de uma thread. É neste método que definimos o que o thread vai executar. Thread myThread = new MyThreadClass(); myThread.start();
Falamos em “Ready“ (Pronto), porque a thread pode não estar realmente sendo executada no estado de Ready (Pronto). Imagine um computador com um único processador - seria impossível executar todos as threads “prontas" ao mesmo tempo. O que ocorre é que o processador deve ser escalonada entre as vários threads.
Estado Running (Executando) Quando o Scheduler escalona uma thread para o processador, esta passa ao estado de “Running”. Quando uma thread está em “Running” (Executando), as instruções do seu método run() estão sendo executadas pelo processador.
Running Ready Se uma thread está no estado “Running”, ela pode passar ao estado “Ready” , se um método yield()for executado. Ou pode passar do estado “Running” para o estado NOT-RUNNABLE.
Em NOT-RUNNABLE O estado NOT-RUNNABLE significa que a thread está impedido de executar por alguma razão. Existem 3 maneiras através das quais um thread ir para um estado NOT-RUNNABLE: A thread executa um método sleep() O thread bloqueia, esperando por I/O. O thread usa seu método wait() para esperar por uma condição.
Estados NOT-RUNNABLE (Suspenso) “Dormindo” – TIME-WAITING - em espera temporizada; a thread executou o método sleep(). Para retornar de “Dormindo”, tempo tem que terminar. “Bloqueado” – BLOCKED - aguarda I/O; I/O precisa ser completado. Para retornar de I/O, o I/O tem que terminar. “Em Espera” - WAITING - a thread executou um método wait(); aguarda uma condição ser satisfeita; o objeto que a "segura" precisa liberá-la, através de um método notify() ou de um método notifyAll()
Saindo de NOT-RUNNABLE Para cada forma de entrar no estado Non-Runnable, alguma forma específica fará o thread retornar para o estado Runnable. Veremos detalhes adiante quando falarmos de sincronização de thread .
Arquitetura do Pool de Threads Uma das possíveis arquiteturas baseadas em Threads, chama-se Pool de Threads. Um Pool de Threads é criado e gerenciado quando o aplicativo é executado.
Pool de Threads Em sua forma mais simples, o aplicativo cria um “Pool de Threads Trabalhadoras” para processar os pedidos de execução de threads. No caso de haver um número fixo de threads trabalhadoras, com menos threads do que o número de threads que pedem execução, a thread requerendo execução será colocada numa fila e atribuída à primeira thread trabalhadora que completar sua tarefa.