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 NonRunnable, 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.