Estudo Certificação Java Capítulo 6 - Threads. Estudo Certificação Java Roteiro O que uma...

Preview:

Citation preview

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;

}

}

}

Recommended