Concorrência em Java Threads em Java Máquina Virtual Java, Processos e Threads – Cada instância da JVM corresponde a um processo do sistema operacional hospedeiro. – A JVM não possui o conceito de processos – apenas implementa threads internamente. Máquina Virtual Java, Processos e Threads – Ao ser iniciada, a JVM executa o método main() do programa na thread principal, e novas threads podem ser criadas a partir desta. – Threads de uma mesma JVM compartilham memória, portas de comunicação, arquivos e outros recursos. Prioridade de Threads • Valor de 1 a 10; 5 é o default. • Threads herdam prioridade da thread que a criou. • Modificada com setPriority(int) . • Obtida com getPriority() . Prioridades de Threads – – – – – – – – – – 10 9 8 7 6 5 4 3 2 1 -> A -> B C D -> E -> F G H -> I -> J -> K Escalonamento de Threads • Threads com prioridades iguais são escalonadas em round-robin (rodízio), com cada uma ativa durante um quantum. Escalonamento Pré-Emptivo • Threads de alta prioridade são executadas por um quantum, no esquema de rodízio até que as threads sejam concluídas. Threads • Implementação de Threads no Java – Green Threads • Usadas em sistemas sem suporte a threads. • Threads e escalonamento implementados pela máquina virtual Java. – Threads Nativas • Usa threads nativas e escalonador do S.O. • Usada nos sistemas suportados oficialmente. – Linux, Solaris e Windows • Ideal em máquinas com >1 processador. Ciclo de Vida de uma Thread Estados das Threads em Java • Nascimento • Pronta: poderia ser executada, mas o processador está ocupado. • Em execução: quando está rodando. • Suspensa: – – – – Bloqueada: aguarda operação de I/O. Em Espera: aguarda alguma condição. Dormindo: suspensa por um tempo de adormecimento. Morta, quando é terminada. Principais métodos de java.lang.Thread • run() contém o código executado pela thread. • start() dispara a execução de uma thread, que por sua vez chama o método run(). Outros métodos de java.lang.Thread • setName: configura o nome de uma thread. • getName devolve o nome de uma thread. • currentThread() devolve uma referência da thread em execução. • sleep() especifica quanto tempo a thread deve dormir. • interrupt() interrompe uma thread. Outros métodos de java.lang.Thread • isInterrupted determina se a thread foi interrompida. • isAlive() devolve true se a thread não estiver morta. • join() espera que a thread para a qual uma msg foi enviada, morra antes que a thread chamadora possa prosseguir. Outros métodos de java.lang.Thread • wait a thread entra num estado de espera por um recurso/objeto particular para o qual o wait foi chamado. • notify a thread em estado de espera torna-se pronta quando uma chamada notify é emitida por outra thread associada com aquele recurso/objeto. • notifyAll todas as threads em estado de espera por um objeto tornam-se prontas quando notifyAll é feita por outra thread associada com aquele objeto. Nome da Thread • Identificador não-único da Thread. • Pode ser definido ao criar a Thread com Thread(String) ou Thread(Runnable, String) • Se não for definido na criação, o nome da Thread será “Thread-n” (com n incremental) • Pode ser redefinido com setName(String) • Pode ser obtido através do método getName() Threads na Linguagem Java • O conceito de thread está presente em Java através da classe java.lang.Thread . • Java também oferece : – Mecanismos para sincronização e controle de concorrência entre threads (monitor, semáforo e Locks). Pool de Threads – Quando um programa possui muitas threads para serem executadas, pode-se agrupar threads para definir o que se chama de um pool de threads. – Java oferece classes e interfaces que facilitam o gerenciamento de um pool de threads. – Classes para gerenciamento de um pool de threads, existem e exemplos podem ser vistos em Deitel , Ed.6, Cap. 23, exemplos 25-4 e 23-5. Gerenciando um Pool de Threads • java.lang.Object java.util.concurrent.Executors • A classe Executors estende a classe raiz Object. • A classe Executors gerencia um grupo de threads. – Interface Executor – Interface ExecutorService Interfaces e Classes para Gerenciar Pools de Threads • interface Runnable, para construir threads. • interface Executor • classe Executors (com s no final é uma classe). • interface ExecutorService, para gerenciar threads através de seu método execute. Interface Executor • public interface Executor • Uma interface com operações para criar um objeto que executa tarefas submetidas via interface Runnable. • Esta interface provê um modo de desacoplar submissão de tarefa, do mecanismo de como cada tarefa será executada, incluindo detalhes do uso de threads, scheduling e outras coisas. Interface Executor • Uma interface Executor é normalmente usada, ao invés de explicitamente criar threads. • java.util.concurrent.Executor • ExecutorService é sub-interface de Executor. Classe Executors • java.lang.Object java.util.concurrent.Executors • public class Executors extends Object • Executors contém métodos que criam e retornam um ExecutorService . Interface ExecutorService • public interface ExecutorService extends Executor • Para usar pools de threads, instancie uma implementação da interface ExecutorService e entregue tarefas para execução. Interface ExecutorService • As implementações de ExecutorService permitem que você estabeleça: – O número máximo do pool (número de threads). – O tipo de estrutura de dados para armazenar as tarefas. – Como criar e terminar threads. – Como tratar tarefas rejeitadas, quando o número de tarefas é maior que o número de threads no Pool de Threads. Interface ExecutorService • Especificamos o número de tarefas ("worker threads“) a criar e o tamanho do pool de threads usados para executar as tarefas. Pool de tamanho fixo • Um pool pode usar um número fixo de threads. • newFixedThreadPool(int) Cria um pool com número fixo de threads dado por int e uma fila ilimitada de tarefas. Fixando número de threads // cria ExecutorService para gerenciar threads ExecutorService threadExecutor = Executors.newFixedThreadPool(3); Threads sob Demanda newCachedThreadPool() • Cria um pool de threads sem limite, com recuperação automática de threads (threads que já terminaram as tarefas são reutilizados para novas tarefas e novos threads são criados só se não houver thread "velha" disponível). • É uma boa opção quando há muitas tarefas pequenas a executar assincronamente. • Threads não usados por 60 segundos são removidos Pool de Threads • Outro caso, por exemplo, pode usar um número fixo de threads, com menos threads do que tarefas. • Pool de Threads