Professional Documents
Culture Documents
Programao concorrente
O objetivo deste mdulo oferecer uma introduo a Threads que permita o seu uso em aplicaes grficas e de rede Tpicos abordados
A classe Thread e a interface Runnable Como criar threads Como controlar threads Tpicos sobre deadlock Exemplos de monitores: wait() e notify()
O que um thread
Um thread parece e age como um programa individual. Threads, em Java, so objetos. Individualmente, cada thread faz de conta que tem total poder sobre a CPU Sistema garante que, de alguma forma, cada thread tenha acesso CPU de acordo com
Cotas de tempo (time-slicing) Prioridades (preemption)
Em alguns tipos de aplicaes, threads adicionais so essenciais. Em outras, podem melhorar o bastante a performance. Interfaces grficas
Essencial para ter uma interface do usurio que responda enquanto outra tarefa est sendo executada
Rede
Essencial para que servidor possa continuar a esperar por outros clientes enquanto lida com as requisies de cliente conectado. 5
Ciclo de vida
Um thread est geralmente em um dentre trs estados: executvel (e possvelmente executando) e no-executvel (esperando, bloqueado, etc.) O thread entre no estado executvel com t.start(), que causa o incio de run(), e passa para o estado morto quando run() chega ao fim.
Executando (running)
t.yield() t.setPriority() Thread t = new Thread() t.start() Thread.sleep(1000) blocked (socket, file, ...) object.wait() esperando acesso ...
Executvel (ready)
run() terminou
No executvel
Morto
10
Filas de prioridades
O estado ready no garantia de execuo. Threads so regidos por prioridades. Threads de baixa prioridade tm menos chances
Ready (filas)
9 5 5 5 3 3 3 3 1
Running (CPU)
Um thread terminou
5 5 5 3 3 3 3 1 9
Sleeping
9 9
Dead
Outro dorme
5 5 3 3 3 3 1
5 5 3 3 3 3 1
11
De instncia
void run(): o "main" do Thread. Deve ser implementado no Thread ou no objeto Runnable passado ao thread void start(): um bootstrap. Faz o JVM chamar o run() boolean isAlive(): verifica se thread est vivo
12
sacar(1000)
13
Corrupo
Recursos compartilhados devem ser protegidos A palavra-reservada synchronized permite que blocos sensveis ao acesso simultneo sejam protegidos de corrupo impedindo que objetos os utilizem ao mesmo tempo. Thread 1 Thread 2 Synchronized deve limitar-se aos saldo(): 1200 trechos crticos (performance!)
void operacaoCritica() { // ... trechos thread-safe synchronized (this) { if (saldo() > 1000) sacar(1000); else depositar(500); } // (... trechos seguros ...) }
espera() sacar(1000) saldo(): 200 depositar(500) Thread 1 tem monoplio do objeto enquanto estiver no bloco synchronized
14
Esse controle possvel atravs de dois mtodos da classe Object, que s podem ser usados em blocos synchronized
wait(): faz com que o Thread sobre o qual chamado espere por um tempo indeterminado, at receber um... notify(): notifica o prximo Thread que o recurso bloqueado foi liberado. Se h mais threads interessados, deve-se usar o notifyAll(): avisa a todos os threads.
15
16
17
18
19
Problemas de sincronizao
Quando mtodos sincronizados chamam outros mtodos sincronizados h risco de deadlock Exemplo: para alterar valor no objeto C:
O Thread A espera liberao de acesso a objeto que est com Thread B O Thread B aguarda que algum (A, por exemplo) faa uma alterao no objeto para que possa liber-lo (mas ningum tem acesso a ele, pois B o monopoliza!)
Soluo
Evitar que mtodos sincronizados chamem outros mtodos sincronizados Se isto no for possvel, controlar liberao e retorno dos acessos (hierarquia de chaves de acesso)
20
Exemplo de deadlock
public class Caixa { double saldoCaixa = 0.0; Cliente clienteDaVez = null; public synchronized void atender(Cliente c, int op, double v) { while (clienteDaVez != null) { wait(); } //espera vez clienteDaVez = c; switch (op) { case -1: sacar(c, v); break; case 1: depositar(c, v); break; } } private synchronized void sacar(Cliente c, double valor) { while (saldoCaixa <= valor) { wait(); } //espera saldo, vez if (valor > 0) { saldoCaixa -= valor; clienteDaVez = null; notifyAll(); } } private synchronized void depositar(Cliente c, double valor) { if (valor > 0 ) { saldoCaixa += valor; clienteDaVez = null; notifyAll(); } }
21
Deadlock (2)
Cenrio 1:
Saldo do caixa: R$0.00 Cliente 1 (thread) atendido (recebe acesso do caixa), deposita R$100.00 e libera o caixa Cliente 2 (thread) atendido (recebe o acesso do caixa), saca R$50.00 e libera o caixa
Exerccios
1. Implemente e rode o exemplo Trabalhador mostrado neste captulo 2. Altere a classe para que o Thread rode para sempre
Crie um mtodo parar() que altere um flag que faa o loop infinito terminar
3. Implemente e rode o exemplo Produtor Consumidor 4. Implemente o exemplo de deadlock e encontre um meio de evit-lo.
23
argonavis.com.br
24