1 / 33

Sincronização de Threads

Sincronização de Threads. Professor: Hyggo Almeida. O que vimos na última aula ?. Threads Ciclo de vida Escalonamento. O que veremos hoje ?. Threads Sincronização. Sincronização de Threads. As threads vistas até agora são executadas paralelamente Mas não há recursos compartilhados

keith
Télécharger la présentation

Sincronização de Threads

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Sincronização de Threads Professor: Hyggo Almeida

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

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

  4. 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!!! Sincronização de Threads

  5. 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 Sincronização de Threads

  6. Sincronização de Threads • Produtor publicclass Producer extends Thread { privateSharedResourceresource; privateintnumber; public Producer(SharedResourcec, intnumber) { resource = c; this.number = number; } publicvoidrun() { for (inti = 0; i < 10; i++) { resource.put(i); try{ sleep((int)(Math.random() * 100)); } catch (InterruptedException e) { } } } } Sincronização de Threads

  7. Sincronização de Threads • Produtor public class Consumer extends Thread { private SharedResource resource; private int number; public Consumer(SharedResource c, int number) { resource = c; this.number = number; } publicvoid run() { int value = 0; for (int i = 0; i < 10; i++) { value = resource.get(); } } } Sincronização de Threads

  8. 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? Sincronização de Threads

  9. 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 consumidorperde 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 Sincronização de Threads

  10. 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 Sincronização de Threads

  11. 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 palavrasynchronized public class SharedResource { private int contents; private boolean available = false; public synchronized int get() { ... } public synchronized void put(int value) { ... } } Sincronização de Threads

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

  13. Sincronização de Threads • Sincronização via locking • Locking reentrante public class Reentrant { public synchronized void a() { b(); System.out.println(“Estou em a()”); } public synchronized void b() { System.out.println(“Estou em b()”); } } Sincronização de Threads

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

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

  16. 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 Sincronização de Threads

  17. 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) Sincronização de Threads

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

  19. 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 Sincronização de Threads

  20. 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 Lock aLock = new ReentrantLock(); … aLock.lock(); try{ \\… }finally{ aLock.unlock(); } Sincronização de Threads

  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 • 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 ocorreu Sincronização de Threads

  22. 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. Sincronização de Threads

  23. Sincronização de Threads • Locks explícitos e variáveis condicionais • Exemplo da classe SharedResource import java.util.concurrent.locks.*; public class SharedResource { privateint contents; privateboolean available = false; private Lock aLock = new ReentrantLock(); private Condition condVar = aLock.newCondition(); //… } Sincronização de Threads

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

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

  26. 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 Sincronização de Threads

  27. 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() Sincronização de Threads

  28. Sincronização de Threads • Sincronizando coleções • Apenas a lista decorada deve ser usada a partir de então... • Iterações devem ser sincronizadas... List list = Collections.synchronizedList(new ArrayList()); synchronized(list) { Iterator i = list.iterator(); // Deve estar dentro do bloco while (i.hasNext()) foo(i.next()); } Sincronização de Threads

  29. 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 • Starvationocorre 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 Sincronização de Threads

  30. 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 Sincronização de Threads

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

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

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

More Related