estudo certificação java capítulo 6 - threads. estudo certificação java roteiro o que uma...
TRANSCRIPT
Estudo Certificação Java
Capítulo 6 - Threads
Estudo Certificação Java
RoteiroO que uma thread executaEstados e prioridades de um threadControlando (yelding, suspending, sleeping,
blocking)Monitor States e Implementações de
escalonamento (wait, notify)Lock e sincronizaçãoAlém do modelo puro e maneiras estranhas
de sincronizar
Estudo Certificação Java
O que uma thread executa (1)
Conteúdo do run()Não imediatamente! A invocação do
start() registra aquele código a um escalonador de threads e o torna “elegível” para rodar
2 maneiras: extends Thread e implements Runnable
Estudo Certificação Java
O que uma thread executa (2)public class CounterThread extends Thread{
public void run() {
for (int i=0; i<10;i++) {
System.out.println(“Counting: “+i);
}
}
}
CounterThread ct = new CounterThread();
ct.start();
Estudo Certificação Java
O que uma thread executa (3)
public class DownCounter implements Runnable{
public void run() {
for (int i=10; i>=1;i--) {
System.out.println(“Counting down: “+i);
}
}
}
DownCounter dc = new DownCounter();
Thread t = new Thread(dc);
t.start();
Estudo Certificação Java
O que uma thread executa (4) implements vs. extends
extends tem o problema de não haver herança múltipla em Java
extends é mais simples implements está mais de acordo com a idéia de OO: o
fato de uma classe se comportar como uma thread não necessariamente justifica a “força” de dizer que “é uma Thread”
voltando do run a Thread está morta: não pode restartar, mas pode invocar seus métodos
stop() não existe no 1.2: usar interrupt()
Estudo Certificação Java
Estados de uma Thread
MonitorStates
Running
Ready
Suspended Asleep Blocked
suspend deprecated apenas o escalonador pode mexer numaready thread
Estudo Certificação Java
Prioridades de uma ThreadInteiros de 1 a 10. Geralmente escolhe-
se entre as waiting threads de maior prioridade
Não há garantia de que a que espera há mais tempo será escolhida
Default é 5, mas as novas são criadas com a prioridade da Thread que as criou
int oldPriority = theThread.getPriority();
int newPriority = Math.min(oldPriority+1,Thread.MAX_PRIORITY);
theThread.setPriority(newPriority);
Estudo Certificação Java
Controlando Threads (1)Yeld: de Running p/ Ready
permite que outras Threads que estejam “waiting” seja escalonadas
se não houver outras esperando, então continua rodando imediatamente
exemplo: rotina pesada faz um yeld periodicamente p/ dar tempo da GUI atuar (botão “interromper” poder ser pressionado)
vale a pena diminuir prioridade também, mas não é garantia de funcionar em todas plataformas
Estudo Certificação Java
Controlando Threads (2)Suspending: não caem na prova Sleeping: mantém dormindo por um
período (milisegundos e nanosegundos opcionalmente) tempo expirado ou interrupt -> Ready como yeld é método estático havendo interrupt() sobre ela, joga
InterruptedException ao voltar p/ “Running” state
Estudo Certificação Java
Controlando Threads (3)Blocking: de Running p/ Blocked
usada para esperar que alguma condição ocorra: exemplo I/O
try {
Socket sock = new Socket(“magnesium”, 5505);
InputStream istr = sock.getInputStream();
int b = istr.read();
} catch (IOException ex) {}
sai desse estado quando a condição é satisfeita, ou quando ocorre interrupt
Estudo Certificação Java
Monitor states são bem diferentes dos demais
wait() coloca em espera e notify() (e notifyAll()) de volta a Ready: são implementados em Object só podem ser chamados em código
synchronizedPodem ser preemptivo ou time-sliced:
depende da plataforma
Monitores wait() e notify() (1)
Estudo Certificação Java
class Mailbox {
public boolean request; public String message; }
public class Consumer extends Thread {
private Mailbox myMailbox;
public Consumer (Mailbox box) { this.myMailbox = box;}
public void run() {
while (true) {
if (myMailbox.request) {
System.out.println(myMailbox.message);
myMailbox.request = false;
}
try {sleep(50);} catch (InterruptedException e) {}
}
}
Monitores wait() e notify() (2)
Estudo Certificação Java
Nada impede que entre o checar o request e imprimir, outra thread mude a mensagem
A escolha do tempo de verificação do “request” é difícil
Os recursos compartilháveis tem que estar protegidos (synchronized)
Quem verifica “request” deve esperar um tempo razoável e ser notificado de sua mudança
Monitores wait() e notify() (3)
Estudo Certificação Java
Marca-se código com “synchronized” e a VM faz: um thread que quiser executar tal código tem
que obter o lock se lock não estiver disponível, fica no estado
de esperando lock quando lock é obtido a thread vai para Ready
marca-se método como “synchronized” ou parte de um código
Lock e Sincronização (1)
Estudo Certificação Java
Mas ainda tem-se o problema dos clientes de como eles vão saber e esperar pelo lock para chamar store e retrieve
Lock e Sincronização (2)class Mailbox {
private boolean request;
private String message;
public synchronized void storeMessage(String message) { request = true;
this.message = message;}
public synchronized String retrieveMessage() {
request = false;
return message;
}
Estudo Certificação Java
Lock e Sincronização (3)
Running
Ready
WaitingSeekinglock Notify, notifyAll,
timeout ou interrupt
Entra em código synchronized
wait
Lock obtido
escalonado
Estudo Certificação Java
Lock e Sincronização (4)public synchronized String retrieveMessage() {
while (request == false) {
try { wait(); }
catch (InterruptedException e) {}
}
request = false;
return message;
}
public synchronized void storeMessage(String message) {
this.message = message;
request = true;
notify();
}
Estudo Certificação Java
Se um consumidor quiser chamar retrieve num objeto sem mensagem ele entra no waiting state
Em algum momento um produtor coloca uma mensagem e por conseguinte muda o request e notifica
O consumidor vai para “seeking lock” e quando o obtém imprime uma mensagem consistente
Lock e Sincronização (5)
Estudo Certificação Java
Lock e Sincronização (6)public synchronized String retrieveMessage() {
while (request == false) {
try { wait(); }
catch (InterruptedException e) {}
}request = false; notify(); return message;
}
public synchronized void storeMessage(String message) {
while (request == true) {
try {wait(); }
catch (InterruptedException e) {}
} request = true;
this.message = message;
notify();
} Resolve problema de produtor usar store quandojá há message
Estudo Certificação Java
Wait. A thread que a chamou: desiste da CPU desiste do lock vai p/ o “pool” de monitores em “waiting”
notify: sái do “pool” de monitores em “waiting” e vai p/ o estado de “seeking lock” terá de re-adquirir o lock p/ prosseguir
Resumindo wait e notify
Estudo Certificação Java
Usar while ao invés de if p/ continuar esperando no caso do estado não estar ok
usar notifyAll ao invés de notify p/ notificar todas as threads
Além do modelo puro (+ de 1 produtor/consumidor)
public synchronized void mixedUpMethod {
while (i< 16 || f > 4.3f || message.equals(“UH-HO”) {
try { wait(); }
catch (InterruptedException e) {}
}
// modifica o estado do monitor e…
notifyAll();
}
Estudo Certificação Java
Fazer lock de uma porção do código em relação a um determinado objeto
provável objetivo: liberar locks o quanto antes não bloqueando o método inteiro
lock também pode ser sobre this
Maneiras estranhas de sincronizar
class Strange Sync {
Rectangle rect = new Rectangle(11, 13, 1100, 1300);
void doIt() { int x = 504; int y = x/3;
synchronized(rect) {
rect.width -= x;rect.heigth -=y;
}
}
}