A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

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

Apresentações semelhantes


Apresentação em tema: "Sincronização de Threads Professor: Hyggo Almeida Laboratório de Sistemas Embarcados e Computação Pervasiva Centro de Engenharia Elétrica e Informática."— Transcrição da apresentação:

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 Universidade Federal de Campina Grande

2 O que vimos na última aula? Threads Ciclo de vida Ciclo de vida Escalonamento Escalonamento 2 Sincronização de Threads

3 O que veremos hoje? Threads Sincronização Sincronização 3 Sincronização de Threads

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

5 Produtor/Consumidor Um produtor gera um número entre 0 e 9 e o armazena em uma instância de SharedResource 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 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 O consumidor consome os números inteiros acessando a mesma instância de SharedResource 5 Sincronização de Threads

6 Produtor 6 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) { } }

7 Sincronização de Threads Produtor 7 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(); }

8 Sincronização de Threads Produtor/Consumidor O produtor e o consumidor compartilham dados da instância de SharedResource O produtor e o consumidor compartilham dados da instância de SharedResource O consumidor deve receber um dado número apenas uma vez... O consumidor deve receber um dado número apenas uma vez mas quem está controlando isso?... mas quem está controlando isso? 8 Sincronização de Threads

9 Produtor/Consumidor Uma vez que não há sincronização na execução das threads, pode-se ter duas situações indesejadas: 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 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 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 Esse tipo de problema é denominado condição de corrida 9 Sincronização de Threads

10 Condição de corrida Quando duas ou mais threads ou processos compartilham dados e o resultado final depende do escalonamento 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 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 Fazer com que cada thread coordene seu trabalho, notificando a outra thread quando o número foi produzido e consumido 10 Sincronização de Threads

11 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 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 Uma região crítica é demarcada pela palavra synchronized 11 Sincronização de Threads public class SharedResource { private int contents; private boolean available = false; public synchronized int get() {... } public synchronized void put(int value) {... }

12 Sincronização de Threads Sincronização via locking Bloco avulso de código Bloco avulso de código 12 Sincronização de Threads //.. synchronized { //qualquer trecho de código } //.. synchronized (obj){ //qualquer trecho de código }

13 Sincronização de Threads Sincronização via locking Locking reentrante Locking reentrante 13 Sincronizaçã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()); }

14 Sincronização de Threads Sincronização via wait e notifyAll 14 Sincronizaçã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; }

15 Sincronização de Threads Sincronização via wait e notifyAll 15 Sincronizaçã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(); }

16 Sincronização de Threads Sincronização via wait e notifyAll O método wait libera o lock e espera notificação para continuar 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) 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 Ao acordar, tem-se o lock novamente O método notifyAll acorda todas as threads que estão em wait (nesse objeto) O método notifyAll acorda todas as threads que estão em wait (nesse objeto) As threads que acordam competem pelo lock As threads que acordam competem pelo lock Quando uma thread tem o lock, as outras dormem Quando uma thread tem o lock, as outras dormem 16 Sincronização de Threads

17 Sincronização via wait e notifyAll Há também o método notify (escolha arbitrária) 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) 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() espera uma condição para o objeto corrente e esta condição ocorre com notify() no mesmo objeto wait() wait() wait(milisegundos) wait(milisegundos) wait(milisegundos, nanosegundos) wait(milisegundos, nanosegundos) 17 Sincronização de Threads

18 Vamos implementar o exemplo do produtor/consumidor Sincronização de Threads

19 Locks explícitos e variáveis condicionais Pode-se proteger regiões críticas com locks explícitos Pode-se proteger regiões críticas com locks explícitos Permite proteger alguns statements Permite proteger alguns statements Permite proteger múltiplos métodos Permite proteger múltiplos métodos Para criar um lock explícito, instancia-se uma implementação da interface Lock Para criar um lock explícito, instancia-se uma implementação da interface Lock Em geral, ReentrantLock Em geral, ReentrantLock 19 Sincronização de Threads

20 Locks explícitos e variáveis condicionais Para obter o lock, utiliza-se o método lock() Para obter o lock, utiliza-se o método lock() Para liberar... unlock() Para liberar... unlock() Uma vez que o lock não é liberado automaticamente, deve-se usar try...finally para garantir sua liberação Uma vez que o lock não é liberado automaticamente, deve-se usar try...finally para garantir sua liberação 20 Sincronização de Threads Lock aLock = new ReentrantLock(); … aLock.lock(); try{ \\… }finally{ aLock.unlock(); }

21 Sincronização de Threads Locks explícitos e variáveis condicionais Para esperar por um lock explícito, cria-se uma variável condicional Para esperar por um lock explícito, cria-se uma variável condicional Um objeto que implementa a interface Condition Um objeto que implementa a interface Condition Usar Lock.newCondition() para criar uma condição Usar Lock.newCondition() para criar uma condição A condição provê métodos: A condição provê métodos: await() para esperar até a condição ser verdadeira await() para esperar até a condição ser verdadeira signal() e signalAll() para avisar os threads que a condição ocorreu signal() e signalAll() para avisar os threads que a condição ocorreu 21 Sincronização de Threads

22 Locks explícitos e variáveis condicionais Variações de await() Variações de await() await () - Espera uma condição ocorrer. await () - Espera uma condição ocorrer. awaitUninterruptibly() - Espera uma condição ocorrer. Não pode ser interrompido. 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. 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(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. await(Date timeout) - Espera uma condição ocorrer. Espera no máximo até a data especificada. 22 Sincronização de Threads

23 Locks explícitos e variáveis condicionais Exemplo da classe SharedResource Exemplo da classe SharedResource 23 Sincronizaçã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(); //… }

24 Sincronização de Threads Locks explícitos e variáveis condicionais Exemplo da classe SharedResource Exemplo da classe SharedResource 24 Sincronizaçã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; }

25 Sincronização de Threads Locks explícitos e variáveis condicionais Exemplo da classe SharedResource Exemplo da classe SharedResource 25 Sincronizaçã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 produzido condVar.signalAll(); } finally { aLock.unlock(); }

26 Sincronização de Threads Estruturas de dados sincronizadas Em vez de construir estruturas sincronizadas como o SharedObject, pode-se utilizar algumas pré-definidas Em vez de construir estruturas sincronizadas como o SharedObject, pode-se utilizar algumas pré-definidas Classes do pacote java.util.concurrent Classes do pacote java.util.concurrent Exemplo: BlockingQueue Exemplo: BlockingQueue Fila que trata de todos os detalhes de sincronização Fila que trata de todos os detalhes de sincronização 26 Sincronização de Threads

27 Sincronizando coleções As coleções de Java em geral ( ArrayList,...) não são sincronizadas (não são thread-safe) As coleções de Java em geral ( ArrayList,...) não são sincronizadas (não são thread-safe) Exceção é Vector Exceção é Vector Para criar coleções sincronizadas, deve-se criar um decorador da coleção que sincroniza os métodos 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 Java já fornece tais decoradores na classe Collections Collections.synchronizedCollection() Collections.synchronizedCollection() Collections.synchronizedList() Collections.synchronizedList() Collections.synchronizedMap() Collections.synchronizedMap() Collections.synchronizedSet() Collections.synchronizedSet() Collections.synchronizedSortedMap() Collections.synchronizedSortedMap() Collections.synchronizedSortedSet() Collections.synchronizedSortedSet() 27 Sincronização de Threads

28 Sincronizando coleções Apenas a lista decorada deve ser usada a partir de então... Apenas a lista decorada deve ser usada a partir de então... Iterações devem ser sincronizadas... Iterações devem ser sincronizadas Sincronizaçã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()); }

29 Sincronização de Threads Starvation e deadlock... Várias threads competem por recursos... Várias threads competem por recursos... Equidade (fairness) existe quando cada thread recebe recursos suficientes para progredir Equidade (fairness) existe quando cada thread recebe recursos suficientes para progredir Um sistema com equidade deve evitar starvation e deadlock Um sistema com equidade deve evitar starvation e deadlock Starvation ocorre quando uma ou mais threads não conseguem obter recursos para progredir 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 Deadlock é uma starvation que ocorre quando as threads esperam por uma condição que nunca vai ocorrer 29 Sincronização de Threads

30 Starvation e deadlock... Exemplo clássico: filósofos! Exemplo clássico: filósofos! Cinco filósofos estão sentados numa mesa redonda Cinco filósofos estão sentados numa mesa redonda Na frente de cada filósofo, há uma tijela de arroz Na frente de cada filósofo, há uma tijela de arroz Entre cada dois filósofos há um pauzinho chinês 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 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 Os filósofos devem achar uma forma de compartilhar pauzinhos de forma a que todos possam comer Applet: Applet: Sincronização de Threads

31 O que vimos hoje? Threads Sincronização Sincronização 31 Sincronização de Threads

32 O que veremos na próxima aula? Threads Pool Pool 32 Sincronização de Threads

33 Dúvidas? ? 33 Sincronização de Threads


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

Apresentações semelhantes


Anúncios Google