33
Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Embed Size (px)

Citation preview

Page 1: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de ThreadsProfessor: Hyggo Almeida

Laboratório de Sistemas Embarcados e

Computação PervasivaCentro de Engenharia Elétrica e Informática

Universidade Federal de Campina Grande

Page 2: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

O que vimos na última aula?

Threads Ciclo de vida Escalonamento

2Sincronização de Threads

Page 3: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

O que veremos hoje?

Threads Sincronização

3Sincronização de Threads

Page 4: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

As threads vistas até agora são executadas paralelamente Mas não há recursos compartilhados Elas são independentes Não se concorre por recursos... ...não há concorrência!!!

4Sincronização de Threads

Page 5: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Produtor/Consumidor Um produtor gera um número entre 0 e 9 e o

armazena em uma instância de SharedResource O produtor dorme durante um intervalo aleatório

de 0 a 100 ms antes de gerar mais números O consumidor consome os números inteiros

acessando a mesma instância de SharedResource

5Sincronização de Threads

Page 6: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Produtor

6Sincronização de Threads

public class Producer extends Thread { private SharedResource resource; private int number;

public Producer(SharedResource c, int number) { resource = c; this.number = number; }

public void run() { for (int i = 0; i < 10; i++) { resource.put(i); try { sleep((int)(Math.random() * 100)); } catch (InterruptedException e) { } } }}

Page 7: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Produtor

7Sincronização de Threads

public class Consumer extends Thread { private SharedResource resource; private int number;

public Consumer(SharedResource c, int number) { resource = c; this.number = number; }

public void run() { int value = 0; for (int i = 0; i < 10; i++) { value = resource.get(); } }}

Page 8: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Produtor/Consumidor O produtor e o consumidor compartilham dados

da instância de SharedResource O consumidor deve receber um dado número

apenas uma vez... ... mas quem está controlando isso?

8Sincronização de Threads

Page 9: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Produtor/Consumidor Uma vez que não há sincronização na execução

das threads, pode-se ter duas situações indesejadas: O consumidor perde um número... caso o

produtor produza mais rápido um novo número antes que seja consumido...

O consumidor consome números repetidos... caso o produtor não produza um novo número a tempo

Esse tipo de problema é denominado condição de corrida 9Sincronização de Threads

Page 10: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Condição de corrida Quando duas ou mais threads ou processos

compartilham dados e o resultado final depende do escalonamento

As atividades do produtor e do consumidor devem ser sincronizadas em dois passos... Travando o objeto (locking), impedindo que duas threads o

acessem ao simultaneamente Fazer com que cada thread coordene seu trabalho,

notificando a outra thread quando o número foi produzido e consumido

10Sincronização de Threads

Page 11: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Sincronização via locking Trechos do código que possuem estruturas de dados

acessadas por threads diferentes e concorrentes são chamados regiões ou seções críticas

Uma região crítica é demarcada pela palavra synchronized

11Sincronização de Threads

public class SharedResource { private int contents; private boolean available = false;

public synchronized int get() { ... }

public synchronized void put(int value) { ... }}

Page 12: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Sincronização via locking Bloco “avulso” de código

12Sincronização de Threads

//..synchronized {

//qualquer trecho de código}

//..synchronized (obj){

//qualquer trecho de código}

Page 13: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Sincronização via locking Locking reentrante

13Sincronização de Threads

public class Reentrant { public synchronized void a() { b(); System.out.println(“Estou em a()”); }

public synchronized void b() { System.out.println(“Estou em b()”); }}

Page 14: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Sincronização via wait e notifyAll

14Sincronização de Threads

public synchronized int get() { while (available == false) { try { //esperar o produtor avisar que produziu wait(); } catch (InterruptedException e) { } } available = false; //notificar produtor de que o valor foi recuperado notifyAll(); return contents;}

Page 15: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Sincronização via wait e notifyAll

15Sincronização de Threads

public synchronized void put(int value) { while (available == true) { try { //Esperar aviso do consumidor de que recuperou número wait(); } catch (InterruptedException e) { } } contents = value; available = true; //Notificar consumidor de que número foi produzido notifyAll();}

Page 16: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Sincronização via wait e notifyAll O método wait libera o lock e espera

notificação para continuar Para que outra thread possa adquirir o lock, fazer

seu trabalho e então “acordar” a original (com notifyAll)

Ao acordar, tem-se o lock novamente

O método notifyAll “acorda” todas as threads que estão em wait (nesse objeto) As threads que acordam competem pelo lock Quando uma thread tem o lock, as outras dormem

16Sincronização de Threads

Page 17: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Sincronização via wait e notifyAll Há também o método notify (escolha

arbitrária) Só se pode usar wait(), notify() e notifyAll()

quando se está de posse do lock do objeto (dentro de um bloco synchronized)

wait() espera uma condição para o objeto corrente e esta condição ocorre com notify() no mesmo objeto wait() wait(milisegundos) wait(milisegundos, nanosegundos) 17Sincronização de Threads

Page 18: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Vamos implementar o exemplo do produtor/consumidor...

18Sincronização de Threads

Page 19: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Locks explícitos e variáveis condicionais Pode-se proteger regiões críticas com locks

explícitos Permite proteger alguns statements Permite proteger múltiplos métodos

Para criar um lock explícito, instancia-se uma implementação da interface Lock Em geral, ReentrantLock

19Sincronização de Threads

Page 20: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Locks explícitos e variáveis condicionais Para obter o lock, utiliza-se o método lock() Para liberar... unlock() Uma vez que o lock não é liberado

automaticamente, deve-se usar try...finally para garantir sua liberação

20Sincronização de Threads

Lock aLock = new ReentrantLock();…aLock.lock();try{\\…}finally{ aLock.unlock();}

Page 21: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Locks explícitos e variáveis condicionais Para esperar por um lock explícito, cria-se uma

variável condicional Um objeto que implementa a interface Condition

Usar Lock.newCondition() para criar uma condição

A condição provê métodos: await() para esperar até a condição ser

verdadeira signal() e signalAll() para avisar os

threads que a condição ocorreu21Sincronização de Threads

Page 22: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Locks explícitos e variáveis condicionais Variações de await()

await () - Espera uma condição ocorrer. awaitUninterruptibly() - Espera uma condição ocorrer. Não pode ser

interrompido. awaitNanos(long timeout) - Espera uma condição ocorrer. Espera

no máximo timeout nanossegundos. await(long timeout, TimeUnit unit) - Espera uma condição ocorrer.

Espera no máximo timeout TimeUnit. await(Date timeout) - Espera uma condição ocorrer. Espera no

máximo até a data especificada.

22Sincronização de Threads

Page 23: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Locks explícitos e variáveis condicionais Exemplo da classe SharedResource

23Sincronização de Threads

import java.util.concurrent.locks.*;public class SharedResource { private int contents; private boolean available = false; private Lock aLock = new ReentrantLock(); private Condition condVar = aLock.newCondition(); //…}

Page 24: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Locks explícitos e variáveis condicionais Exemplo da classe SharedResource

24Sincronização de Threads

public int get() { aLock.lock(); try { while (available == false) { try {

condVar.await(); //Esperar aviso de produção} catch (InterruptedException e) { }

} available = false;

//Notificar produtor de que número foi consumido condVar.signalAll(); } finally { aLock.unlock(); return contents; } }

Page 25: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Locks explícitos e variáveis condicionais Exemplo da classe SharedResource

25Sincronização de Threads

public void put(int value) { aLock.lock(); try { while (available == true) { try {condVar.await();//Esperar aviso de que foi consumido

} catch (InterruptedException e) { } } contents = value; available = true;

//Notificar consumidor de que número foi produzidocondVar.signalAll();

} finally { aLock.unlock(); } }}

Page 26: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Estruturas de dados sincronizadas Em vez de construir estruturas sincronizadas

como o SharedObject, pode-se utilizar algumas pré-definidas Classes do pacote java.util.concurrent Exemplo: BlockingQueue

Fila que trata de todos os detalhes de sincronização

26Sincronização de Threads

Page 27: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Sincronizando coleções As coleções de Java em geral (ArrayList, ...) não

são sincronizadas (não são thread-safe) Exceção é Vector

Para criar coleções sincronizadas, deve-se criar um decorador da coleção que sincroniza os métodos Java já fornece tais decoradores na classe Collections

Collections.synchronizedCollection() Collections.synchronizedList() Collections.synchronizedMap() Collections.synchronizedSet() Collections.synchronizedSortedMap() Collections.synchronizedSortedSet()

27Sincronização de Threads

Page 28: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Sincronizando coleções Apenas a lista decorada deve ser usada a partir

de então...

Iterações devem ser sincronizadas...

28Sincronização de Threads

List list = Collections.synchronizedList(new ArrayList());

synchronized(list) { Iterator i = list.iterator(); // Deve estar dentro do bloco while (i.hasNext()) foo(i.next());}

Page 29: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Starvation e deadlock... Várias threads competem por recursos...

Equidade (fairness) existe quando cada thread recebe recursos suficientes para progredir

Um sistema com equidade deve evitar starvation e deadlock Starvation ocorre quando uma ou mais

threads não conseguem obter recursos para progredir

Deadlock é uma starvation que ocorre quando as threads esperam por uma condição que nunca vai ocorrer 29Sincronização de Threads

Page 30: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Sincronização de Threads

Starvation e deadlock... Exemplo clássico: filósofos!

Cinco filósofos estão sentados numa mesa redonda

Na frente de cada filósofo, há uma tijela de arroz Entre cada dois filósofos há um pauzinho chinês Para poder comer um bocado de arroz, um filósofo

deve ter 2 pauzinhos: o da esquerda e da direita Os filósofos devem achar uma forma de

compartilhar pauzinhos de forma a que todos possam comer

Applet: http://dsc.ufcg.edu.br/~jacques/cursos/map/html/threads/sincronizacao.html

30Sincronização de Threads

Page 31: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

O que vimos hoje?

Threads Sincronização

31Sincronização de Threads

Page 32: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

O que veremos na próxima aula?

Threads Pool

32Sincronização de Threads

Page 33: Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática

Dúvidas?

?33Sincronização de Threads