Programação Paralela - Threads

6.459 visualizações

Publicada em

Publicada em: Tecnologia
2 comentários
5 gostaram
Estatísticas
Notas
Sem downloads
Visualizações
Visualizações totais
6.459
No SlideShare
0
A partir de incorporações
0
Número de incorporações
207
Ações
Compartilhamentos
0
Downloads
16
Comentários
2
Gostaram
5
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide

Programação Paralela - Threads

  1. 1. Programação Paralela - Threads Glaucio Scheibel - GUJava/SC
  2. 2. O que é uma Thread? <ul><li>Java é um computador virtual e Thread é a sua CPU virtual. </li></ul><ul><li>Num computador virtual podemos ter quantas CPU’s virtuais quisermos. </li></ul>
  3. 3. Thread: Outras definições <ul><li>Divisão de um processo. SubProcesso. </li></ul><ul><li>Linha de execução. </li></ul>
  4. 4. Tipos de Processo: CPU x IO <ul><li>CPU Bound: processo que se utiliza principalmente de cálculos, dependendo totalmente da CPU. Ex: CAD, Jogos. </li></ul><ul><li>IO Bound: processo que depende principalmente de externos (disco, banco de dados, rede, usuário). Ex: Proc. de dados, ERP, CRM. </li></ul>
  5. 5. Por que usar Thread’s <ul><li>Em aplicações IOBound , que muitas vezes é o mais comum que trabalhamos, desperdiçamos poderosos recursos computacionais na espera deste IO. </li></ul><ul><li>CPU adquirida e sub-utilizada é perda de dinheiro. </li></ul>
  6. 6. A pergunta que não quer calar <ul><li>Por que processar um a um, se podemos forçar a CPU e processar dois a dois ou três a três ou sei lá, Dez, Cem, Duzentos, Mil! </li></ul><ul><li>Ou até tudo de uma só vez. </li></ul><ul><li>Ex clássico: Calculo da folha de pagamento. </li></ul>
  7. 7. Programa sem Threads
  8. 8. Programa com Threads
  9. 9. Concorrência X Paralelismo Tarefa Tarefa Tempo Tempo
  10. 10. Concorrência X Paralelismo <ul><li>Para termos a real paralelismo, precisamos ter mais de uma CPU física e um sistema operacional que as suporte. </li></ul><ul><li>Muitas vezes não há a opção, o sistema possui um modelo, e na programação isto deve estar previsto. </li></ul>
  11. 11. Scheduler / Escalonador <ul><li>Função do sistema operacional que define qual dos processos em execução poderá utilizar-se da CPU. </li></ul><ul><li>Difere de sistema operacional para sistema operacional. </li></ul>
  12. 12. Modelos de Thread <ul><li>Cooperativo </li></ul><ul><li>Preemptivo </li></ul>
  13. 13. Modelo Cooperativo <ul><li>As Thread’s devem cooperar umas com as outras, usando um pouco da CPU de cada vez. </li></ul><ul><li>Fica a cargo das thread’s passar a vez. </li></ul><ul><li>Reduz problemas de sincronização. </li></ul><ul><li>Baseado puramente em prioridades. </li></ul>
  14. 14. Modelo Cooperativo <ul><li>Vantagens: </li></ul><ul><ul><li>Maior velocidade com menos overhead. </li></ul></ul><ul><li>Problemas: </li></ul><ul><ul><li>Thread’s podem tornar-se selfish, ou seja, não liberar mais a CPU. </li></ul></ul><ul><ul><li>Thread’s de menor prioridade podem entrar em starvation , ou seja, não conseguir mais acesso a CPU . </li></ul></ul>
  15. 15. Modelo Preemptivo <ul><li>O sistema operacional utiliza uma espécie de timer para chavear as thread’s. Cada intervalo de execução é chamado de Timer Slice. </li></ul><ul><li>Quando uma thread recebe a CPU, já esta pré-definido este tempo de uso. </li></ul>
  16. 16. Modelo Preemptivo <ul><li>Vantagens: </li></ul><ul><ul><li>Facilidade de programação. </li></ul></ul><ul><ul><li>Teoricamente evita starvation. </li></ul></ul><ul><li>Problemas: </li></ul><ul><ul><li>Menos eficiente devido as thread’s serem gerenciadas pelo sistema operacional. </li></ul></ul><ul><ul><li>Necessita de controle de sincronização. </li></ul></ul>
  17. 17. Sun Solaris <ul><li>Modo preemptivo para processos e modo cooperativo para Threads. </li></ul><ul><li>2 31 níveis de prioridade. </li></ul><ul><li>Administrador pode restringir o nível de prioridade dos processos do usuário. </li></ul>
  18. 18. Microsoft Windows NT <ul><li>Modo preemptivo para processos e threads. </li></ul><ul><li>7 níveis de prioridade. </li></ul><ul><li>Priority Boosting (acessível via C). </li></ul>
  19. 19. Java <ul><li>10 níveis de prioridade </li></ul><ul><li>Na maioria dos casos, o Java mapeia suas próprias threads para threads do sistema operacional. Depende da implementação da VM (JRockit). </li></ul>
  20. 20. Considerações na Codificação <ul><li>Assuma o pior caso: </li></ul><ul><ul><li>Posso ser preemptado a qualquer momento. </li></ul></ul><ul><ul><li>Posso ser egoísta ( selfish ). </li></ul></ul><ul><ul><li>Darei preferência as prioridades 1, 5 e 10; pois pode ser que a prioridade 10 não seja maior que a prioridade 9. </li></ul></ul>
  21. 21. Partes de uma Thread Java
  22. 22. Criando o Código da Thread <ul><li>public class Contador implements Runnable { </li></ul><ul><li>private int id; </li></ul><ul><ul><li>public void run() { </li></ul></ul><ul><ul><ul><li>for (int i=1; i <= 10; i++) { </li></ul></ul></ul><ul><ul><ul><ul><li>System.out.println(“i=“ + i); </li></ul></ul></ul></ul><ul><ul><ul><li>} </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul>
  23. 23. Criando a CPU de uma Thread <ul><li>public class Teste { </li></ul><ul><li>public static void main(String[] args) { </li></ul><ul><li>Contador c = new Contador(); </li></ul><ul><li>Thread t = new Thread(c); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
  24. 24. Dados <ul><li>Lembra da variável local “i”? </li></ul><ul><ul><li>for (int i =1; i <= 10; i ++) { </li></ul></ul><ul><ul><ul><li>System.out.println(“i=“ + i ); </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>Variáveis locais são armazenadas nas Threads </li></ul>
  25. 25. Compartilhamento <ul><li>Diferentes Threads podem compartilhar o mesmo código: </li></ul><ul><ul><li>Thread t1 = new Thread( c ); </li></ul></ul><ul><ul><li>Thread t2 = new Thread( c ); </li></ul></ul><ul><ul><li>Thread t3 = new Thread( c ); </li></ul></ul>
  26. 26. Estados da Thread Pronto Rodando Bloqueada
  27. 27. Cooperativo: Passando a Vez <ul><li>Thread.sleep(long milesegundos) </li></ul><ul><ul><li>para a execução da Thread por um tempo pré-determinado. </li></ul></ul><ul><li>Thread.yield() </li></ul><ul><ul><li>passa a vez para outra Thread de igual ou maior prioridade. </li></ul></ul>
  28. 28. Preemptivo: Sincronização <ul><li>Mecanismo para evitar corrupção dos dados num ambiente multi-thread preemptivo. </li></ul><ul><li>Membros dos objetos podem estar sendo invocados simultaneamente por n Threads, sem a certeza de seu término antes da preempção. </li></ul>
  29. 29. Preemptivo: Objeto Monitor <ul><li>Objeto utilizado para servir de semáforo. </li></ul><ul><li>Cada objeto possui um flag que determina qual thread tem o acesso exclusivo. </li></ul><ul><li>Similar à lock de registro num banco de dados </li></ul>
  30. 30. Preemptivo: Sincronização <ul><li>Modificador synchronized. </li></ul><ul><ul><li>O próprio objeto é o monitor. </li></ul></ul><ul><li>synchronized(Object o) {}. </li></ul><ul><ul><li>Bloco sincronizado especificando qual o objeto monitor. </li></ul></ul>
  31. 31. Estados da Thread - Sincronização Pronto Rodando Bloqueada Travada
  32. 32. Notificação de recurso <ul><li>Muitas vezes a Thread recebe a CPU, mas não há recursos para executar. </li></ul><ul><li>A Thread pode registrar-se para receber uma notificação. </li></ul><ul><li>Sempre ligado a um bloco sincronizado. </li></ul>
  33. 33. Notificação de recurso <ul><li>this.wait() </li></ul><ul><ul><li>Aguarda a notificação. </li></ul></ul><ul><li>this.notify() </li></ul><ul><ul><li>Notifica uma das Threads (não é possível dizer qual) que estão aguardando. </li></ul></ul><ul><li>this.notifyAll() </li></ul><ul><ul><li>Notifica todas as Threads que estão aguardando. </li></ul></ul>
  34. 34. Estados da Thread - Sincronização Pronto Rodando Bloqueada Travada Aguardando Notificação
  35. 35. Algumas Dicas <ul><li>Você pode ter ouvido dizer que para melhorar a performance, você deve evitar o uso de sincronização quando escrever e ler dados atômicos. Este aviso está perigosamente errado. </li></ul>
  36. 36. Algumas Dicas <ul><li>Para evitar o risco de DeadLock, nunca ceda o controle de um método ou bloco sincronizado a um cliente. </li></ul><ul><ul><li>Num método sincronizado, evite invocar métodos desconhecidos, como por exemplo, um método abstrato. </li></ul></ul>
  37. 37. Algumas Dicas <ul><li>Sempre faça o menos possível dentro de um bloco sincronizado. </li></ul>
  38. 38. Algumas Dicas <ul><li>Somente execute o método wait() de dentro de um loop. </li></ul><ul><ul><li>O recurso que você estava esperando pode não estar disponível novamente. </li></ul></ul>
  39. 39. Algumas Dicas <ul><li>Qualquer programa que confia no scheduler para a sua correta execução é considerável não-portável. </li></ul>
  40. 40. Obrigado! Perguntas?

×