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 NEW TIMEWAITING READY FINISHED WAITING RUNNING BLOCKED DEAD 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(); Estado Ready • 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. Métodos de Gerenciamento de Threads • Thread(ThreadGroup group, Runnable target, String name) Cria uma nova thread no estado NEW, a qual pertencerá a group e será identificado como name; a thread executará o método run() de target. • setPriority(int newPriority) getPriority() Configura e retorna a prioridade da thread. • run() a thread executa o método run() de seu objeto de destino, caso ele tenha um; caso contrário, ela executa seu próprio método run() (Thread implementa Runnable). Métodos de Gerenciamento de Threads • start() • sleep(int millisecs) • yield() • destroy() Termina (destrói) a thread. Muda o estado da thread de NEW para RUNNABLE. Passa a thread para o estado TIMEWAITING. Libera o processador. Passa a thread do estado RUNNING para o estado READY. Métodos de Sincronização de Threads • wait(long millisecs, int nanosecs) Bloqueia uma thread até uma chamada feita por notify(), notifyAll(), ative a thread. • notify(), notifyAll() Ativa, respcitvamente, uma ou mais threads que tenham chamado wait(). • join(int millisecs) • interrupt() Ativar prematuramente uma thread que esteja em espera. Bloqueia uma thread chamadora até o término de uma outra 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 tarefas programadas com 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, uma thread requerendo execução será colocada numa fila e atribuída à primeira thread trabalhadora que completar sua tarefa.