34
Linguagem de Programação III Multithreading Professora: Bianca de Almeida Dantas E-mail: [email protected] Site: www.biancadantas.com

Aula sobre multithreading

Embed Size (px)

DESCRIPTION

Slides da aula sobre programação usando múltiplas threads em Java.

Citation preview

Page 1: Aula sobre multithreading

Linguagem de Programação III

Multithreading

Professora: Bianca de Almeida Dantas

E-mail: [email protected]

Site: www.biancadantas.com

Page 2: Aula sobre multithreading

TÓPICOS

• Threads

• Ciclo de vida

• Agendamento

• Criação e execução

• Exemplo

• Produtor-Consumidor

• Multithreading com GUI

Essa aula e seus exemplos foram baseados no

capítulo 26 do livro Java - Como Programar, 8ª

Edição (Deitel & Deitel)

Page 3: Aula sobre multithreading

THREADS

• Linhas de execução dentro de um processo. Conhecidas como processos leves.

• Cada thread possui sua pilha de chamadas de métodos e contador de instruções, entretanto a troca de contexto entre threads de um mesmo processo é menos custosa.

• Permite a execução concorrente de trechos de código que independem entre si.

• Se mais de um núcleo de processamento estiver disponível, a execução pode ser paralela.

Page 4: Aula sobre multithreading

• Linhas de execução dentro de um processo. Conhecidas como processos leves.

• Cada thread possui sua pilha de chamadas de métodos e contador de instruções, entretanto a troca de contexto entre threads de um mesmo processo é menos custosa.

• Permite a execução concorrente de trechos de código que independem entre si.

• Se mais de um núcleo de processamento estiver disponível, a execução pode ser paralela.

Page 5: Aula sobre multithreading

• Linhas de execução dentro de um processo. Conhecidas como processos leves.

• Cada thread possui sua pilha de chamadas de métodos e contador de instruções, entretanto a troca de contexto entre threads de um mesmo processo é menos custosa.

• Permite a execução concorrente de trechos de código que independem entre si.

• Se mais de um núcleo de processamento estiver disponível, a execução pode ser paralela.

Page 6: Aula sobre multithreading

THREADS – Ciclo de Vida

Page 7: Aula sobre multithreading

• Novo: a thread acaba de ser criada e ainda não foi iniciada pela primeira vez.

• Executável: a thread está realizando o seu processamento ou pronta para executá-lo.

• Espera: a thread está esperando que outra thread realize uma tarefa. Volta para o estado executável apenas quando outra thread a notifica.

• Espera sincronizada: a thread está esperando por um intervalo máximo de tempo.

Page 8: Aula sobre multithreading

• Bloqueado: a thread tentou realizar uma tarefa que não pôde ser imediatamente completada, ela fica neste estado até que a tarefa seja completada e, então, transita para o estado executável.

• Terminado: uma thread entra neste estado quando finaliza seu processamento (com ou sem sucesso).

Page 9: Aula sobre multithreading

• O estado executável pode ser subdividido em dois estados separados operacionalmente: pronto e em execução.

• O SO oculta a diferença entre esses dois estados da JVM, que os vê unicamente como executáveis.

• Quando uma thread é criada e passa para o estado executável, ela está, na verdade, no estado pronto; quando ela está efetivamente executando, ela está no estado em execução.

Page 10: Aula sobre multithreading

• Despachar uma thread: quando uma thread tem um processador atribuído a ela.

• Geralmente, uma thread executa por um pequeno período de tempo, o chamado quantum ou fração de tempo.

• Quando o quantum termina, a thread passa novamente para o estado pronto.

Page 11: Aula sobre multithreading
Page 12: Aula sobre multithreading

• Agendamento de threads é o processo que o sistema operacional utiliza para definir a ordem de execução de threads.

• O agendador de threads (thread scheduler), em geral, utiliza as prioridades associadas às threads para definir sua política de execução.

• Em Java, as prioridades variam entre MIN_PRIORITY (uma constante de 1) e MAX_PRIORITY (uma constante de 10). Threads, geralmente, são iniciadas com NORM_PRIORITY.

• As três constantes são definidas na classe Thread.

THREADS – Agendamento

Page 13: Aula sobre multithreading

.......

Page 14: Aula sobre multithreading

• Para especificar uma classe cujo código pode ser executado concorrentemente em uma aplicação, pode-se utilizar a interface Runnable.

• As threads podem ser instanciadas passando como argumento um objeto Runnable.

THREADS – Criação e Execução

Page 15: Aula sobre multithreading

EXEMPLO • Código do projeto Multithread2 enviado por e-

mail....

Page 16: Aula sobre multithreading

pool-1-thread-1 escreveu o valor 1 em 0

Próximo índice = 1

pool-1-thread-2 escreveu o valor 11 em 0

Próximo índice = 2

pool-1-thread-1 escreveu o valor 2 em 1

Próximo índice = 3

pool-1-thread-2 escreveu o valor 12 em 2

Próximo índice = 4

pool-1-thread-1 escreveu o valor 3 em 3

Próximo índice = 5

pool-1-thread-2 escreveu o valor 13 em 4

Próximo índice = 6

Conteúdo do vetor:

[11, 2, 12, 3, 13, 0]

Page 17: Aula sobre multithreading

• Como as threads executam independentemente e compartilham um vetor, o resultado pode não ser como desejado.

• Pela saída anterior, vimos que a thread 2 sobrescreveu o valor recém escrito pela thread 1.

• Situações como essa, nas quais não conseguimos garantir que o resultado será coerente e nas quais o resultado dependerá da ordem em que as threads serão escalonadas são chamadas de condições de corrida.

Page 18: Aula sobre multithreading

• O trecho de código no qual as diferentes threads acessam as variáveis compartilhadas (possivelmente, modificando-as) é chamado de seção crítica.

• Resumindo: o código visto não é seguro para threads.

• Para resolver o problema, transformaremos os trechos de acesso às variáveis compartilhadas em operações atômicas, impedindo que mais de uma thread execute tais instruções simultaneamente.

Page 19: Aula sobre multithreading

EXEMPLO • Código do projeto Multithread2 alterado enviado

por e-mail.

• Nesse código, fizemos com que o código do método que adiciona um elemento ao SimpleArray seja atômico. Em Java, isso é feito usando a palavra-chave synchronized.

• Quando uma thread está executando o corpo de um método synchronized, nenhuma outra pode executá-la antes da primeira terminar sua execução.

• A instrução synchronized também pode ser utilizada para trechos de código.

Page 20: Aula sobre multithreading

PRODUTOR-CONSUMIDOR • Um problema clássico da computação que envolve

processos (ou threads) que produzem recursos para serem consumidos por outros.

• Existe um buffer compartilhado para armazenamento dos recursos. O produtor precisa parar de produzir quando o buffer estiver cheio e o consumidor não pode consumir se não houver recurso disponível.

Page 21: Aula sobre multithreading

ABORDAGEM 1

• Utilizar um buffer compartilhado com apenas uma posição (classe BufferSemSincronizacao).

• Não há garantia sobre a ordem de execução das threads, logo, muitas vezes valores são produzidos com o buffer lotado ou, ainda, consumidos antes da produção, levando a resultados inconsistentes.

Page 22: Aula sobre multithreading

ABORDAGEM 2 • Utilizar um buffer compartilhado com apenas uma

posição, mas utilizando ArrayBlockingQueue (classe BufferBloqueante).

• A classe ArrayBlockingQueue pertence ao pacote java.util.concurrent, segura para threads e que implementa a interface BlockingQueue (que estende a classe Queue) e declara os métodos put e take (equivalentes bloqueantes dos métodos offer e poll.

• put coloca um elemento no fim da fila bloqueando se a mesma estiver cheia.

Page 23: Aula sobre multithreading

• take retira um elemento do começo da fila bloqueando se a mesma estiver vazia.

• O tamanho do ArrayBlockingQueue é passado como argumento para o construtor e não é aumentado dinamicamente.

Page 24: Aula sobre multithreading

ABORDAGEM 3 • Utilizar um buffer compartilhado com apenas uma

posição, mas utilizando métodos sincronizados (synchronized).

• Utiliza uma variável booleana ocupado que indica se o buffer está totalmente ocupado ou não.

• O produtor espera enquanto o buffer estiver lotado utilizando uma chamada ao método wait. Similarmente, o consumidor espera enquanto o buffer estiver vazio.

• O método wait faz com que o objeto que o executou libere implicitamente o bloqueio sobre o buffer.

Page 25: Aula sobre multithreading

• O produtor/consumidor só é liberado de sua espera quando for notificado de que o objeto compartilhado já foi utilizado; isso é feito com a chamada a notifyAll.

• O método notifyAll retira do estado de espera todas as threads que estiverem esperando pelo objeto compartilhado, fazendo com que elas passem ao estado executável e tentem readquirir o bloqueio.

Page 26: Aula sobre multithreading

ABORDAGEM 4 • Utilizar um buffer circular compartilhado com 4

posições.

• Permite minimizar o tempo de espera das threads devido ao aumento das posições disponíveis para escrita e leitura.

• Utiliza:

• uma variável auxiliar para controlar quantos elementos válidos realmente há no buffer em um determinado momento.

• Dois índices para indicar onde será feita a próxima leitura ou a próxima escrita.

Page 27: Aula sobre multithreading

MULTITHREADING COM GUI • Aplicativos GUI são desafiantes para programação

multithreaded.

• Aplicativos swing possuem uma única thread, a thread de despacho de eventos, responsável por tratar as interações com os componentes GUI do aplicativo.

• Todas as tarefas que exigem interação com a GUI do aplicativo são colocadas em uma fila de eventos e executadas em sequência pela thread de despacho de eventos.

Page 28: Aula sobre multithreading

• Componentes GUI Swing não são seguros para threads.

• Segurança para threads em aplicativos GUI é obtida assegurando que os componentes Swing são acessado a partir de uma única thread (a de despacho de eventos). Essa técnica é chamada de confinamento de thread.

• Utilizando essa ideia, uma alternativa interessante é colocar as atividades de longa duração, que independem da interface enquanto são executadas, em threads separadas da de despacho de eventos.

Page 29: Aula sobre multithreading

• Essa alternativa evita que a thread de despacho de eventos fique sem responder enquanto espera pelo resultado de tais atividades.

• Para auxiliar na programação dessas atividades mais demoradas em threads separadas, o Java SE 6 fornece a classe SwingWorker. Essa classe pode realizar cálculos demorados e, então, atualizar s componentes Swing a partir da thread de despacho de eventos com base nos resultados dos cálculos.

• SwingWorker implemente a interface Runnable.

Page 30: Aula sobre multithreading

• Métodos comuns de SwingWorker:

• doInBackground: define o cálculo longo na thread trabalhadora;

• done: executado na thread de despacho de eventos quando doInBackground retorna;

• execute: agenda o objeto SwingWorker a ser executado em uma thread trabalhadora;

• get: espera a conclusão do cálculo e retorna o seu resultado;

• publish: envia resultados intermediários dos cálculos para processamento na thread de despacho de eventos.

Page 31: Aula sobre multithreading

• process: recebe os resultados intermediários e os processa na thread de despacho de eventos;

• setProgress: configura a propriedade de progresso para notificar os ouvintes de alteração de propriedade na thread de despacho de eventos de atualizações da barra de progresso.

Page 32: Aula sobre multithreading

EXEMPLO 1: FIBONACCI • No exemplo, forneceremos uma opção para calcular os

termos da sequência de Fibonacci um a um ou para calcular um termo específico (até o 92º) em uma thread trabalhadora.

• SwingWorker é uma classe genérica que recebe dois parâmetros: o primeiro é o tipo retornado pelo método doInBackground e o segundo é o tipo passado entre os métodos publish e process.

Page 33: Aula sobre multithreading

EXEMPLO 2: ÍMPARES • No exemplo, calculamos todos os números ímpares

menores que um valor inteiro fornecido como entrada.

• Para obtenção dos ímpares, utilizamos o crivo de Eratóstenes.

• Os resultados são exibidos em uma área de texto à medida em que são obtidos.

• Uma barra de progresso mostra o quanto do cálculo já foi concluído até um determinado momento.

Page 34: Aula sobre multithreading

REFERÊNCIAS

• Java Como Programar – 8ª Edição. Deitel & Deitel.