2-Concorrência e Paralelismo
2-Concorrência e Paralelismo
Aula 2
Concorrência e Paralelismo
l.bertholdo@ifsp.edu.br
Conteúdo
• Conceitos sobre Concorrência e Paralelismo
• Threads
• Classe Thread
• Interface Runnable
l.bertholdo@ifsp.edu.br
Conceitos sobre Concorrência e Paralelismo
• Sistemas Monotarefa e Multitarefa
• Os primeiros sistemas operacionais suportavam a execução de
apenas uma tarefa por vez. Nesse modelo, o processador e a
memória ficavam dedicados a uma única tarefa.
• Somente após o término da execução de uma tarefa que outra
poderia ser carregada na memória e então executada.
*quantum é o tempo que o sistema operacional disponibiliza para que uma tarefa use o processador.
Quando o quantum de uma tarefa termina, mesmo que ela ainda não tenha terminado, seu contexto é
salvo na sua pilha de execução onde ela parou, e então ela volta para o estado “Pronta”. Quando o
escalonador de processos do sistema operacional disponibilizar novamente o processador para a tarefa,
ela volta então para o estado “Em Execução”. O escalonador é responsável por cuidar dessa fila de
tarefas e decidir quem tem prioridade, intercalando as tarefas para que o processador não fique ocioso.
l.bertholdo@ifsp.edu.br
Conceitos sobre Concorrência e Paralelismo
• Processos e Threads
• Um processo pode ser visto como um container de recursos
(processador, memória etc) utilizados por uma ou mais tarefas.
• Como os recursos são atribuídos aos processos, as tarefas de um
processo compartilham memória entre si. Porém, uma tarefa de
um processo A não consegue usar um recurso do processo B, ou
seja, processos não compartilham suas memórias.
As tarefas de um mesmo processo podem trocar informações facilmente, pois compartilham a mesma
área de memória. Porém, tarefas de processos distintos só conseguem se comunicar com chamadas de
sistema do kernel*, que permitem a comunicação entre processos (IPC - Inter-Process Communication).
Concorrência é sobre lidar com várias coisas em um mesmo intervalo de tempo. Paralelismo
é sobre fazer várias coisas ao mesmo tempo. (Rob Pike, um dos criadores da linguagem Go)
l.bertholdo@ifsp.edu.br
Conceitos sobre Concorrência e Paralelismo
• Paralelismo
• Consiste na execução simultânea de tarefas.
Paralelismo é como um pedágio que permite que carros
avancem em diferentes fluxos simultaneamente.
Threads ____________
____________
____________
____________
____________
____________
l.bertholdo@ifsp.edu.br
Classe Thread
• A criação de uma thread envolve a instanciação (por meio do
operador new) da classe que implementa a thread.
• Para colocar uma thread em execução, é preciso iniciá-la com uma
chamada ao método start, que solicita o escalonamento da thread
para o sistema operacional e a consequente execução do método run.
• A aplicação abaixo instancia e executa três threads idênticas
utilizando a classe ExemploThread:
l.bertholdo@ifsp.edu.br
Classe Thread
• Resultado da execução da classe
TestaThreads:
O resultado mostra as mensagens indicativas de início e fim do teste, bem como as mensagens das
threads (Thread-0, Thread-1 e Thread-2). Mesmo após o final do método main, a execução continua, pois
as três threads ainda não terminaram seu processamento. Note que as mensagens de início, contagem e
fim das threads se misturam, evidenciando sua execução em paralelo e sem qualquer sincronização.
l.bertholdo@ifsp.edu.br
Classe Thread
• Alguns dos principais métodos da classe Thread:
Método Descrição
Thread currentThread() Retorna uma referência para a thread em execução.
String getName(), Obtém ou define o nome da thread.
void setName(String nome)
int getPriority(), Obtém ou define a prioridade da thread por meio das constantes: MAX_PRIORITY,
void setPriority(int prioridade) MIN_PRIORITY e NORMAL_PRIORITY. Por exemplo: t1.setPriority(Thread.MAX_PRIORITY);
void interrupt() Interrompe a execução da thread.
boolean isAlive(), Determina se a thread está em execução, se é um daemon ou se foi interrompida. Obs.:
boolean isDaemon(), Threads daemon (ou threads de serviço) são aquelas que prestam serviços para outras
boolean islnterrupted() threads, enquanto as threads de usuário são todas as demais.
void join(), void join(long millis) Define uma espera para finalização da thread, opcionalmente pelo tempo indicado.
void run() Método que contém o código que será executado pela thread.
void setDaemon(boolean on) Marca a thread como um daemon.
void sleep(long millis) Suspende a thread corrente pelo número de milissegundos indicado.
void start() Inicia a execução da thread.
void yield() Indica para o escalonador que a thread está disposta a ceder o uso do processador.
l.bertholdo@ifsp.edu.br
Classe Thread – Exemplo
• Classe PrimosST (sem thread)
Continuação
l.bertholdo@ifsp.edu.br
Classe Thread – Exemplo
• Ao executar o cálculo para grandes intervalos (por ex.: 1 a 200.000),
a classe PrimosST apresenta um comportamento inadequado:
• Os botões Executar e Limpar não são desabilitados, e o botão Executar fica
com aparência de “travado” durante o processamento.
• Os botões Cancelar e Limpar dão a impressão de que não funcionam
durante o processamento. O mesmo ocorre com os botões para
redimensionar e fechar a janela.
• Os resultados são apresentados somente ao final do processamento.
Aplicação PrimosST durante o processamento
Note que mesmo as modificações na interface solicitadas antes da chamada do cálculo, como a
desabilitação dos botões Limpar e Executar, são renderizadas de fato somente após o cálculo. l.bertholdo@ifsp.edu.br
Classe Thread – Exemplo
• Classe PrimosCT (com thread)
Continuação
l.bertholdo@ifsp.edu.br
Classe Thread – Exemplo
• Classe PrimosCT2 (com thread) – Classe anônima e Expressão lambda
Podemos simplificar o código da classe PrimosCT
com o uso de classes anônimas e expressões
lambda, eliminando a necessidade de criar a classe
interna Calculo. O código destacado no método
actionPerformed retorna uma instância de uma
classe anônima que implementa o método run da
interface Runnable. No caso, esta implementação é
o próprio código da thread a ser executada. Essa
mesma estratégia é usada no método main.
Continuação
l.bertholdo@ifsp.edu.br
Classe Thread – Exemplo
• Classe anônima é uma classe interna sem nome, que é subclasse de
outra classe ou implementa uma interface, e tem a função de
instanciar um único objeto. Seu objetivo é evitar a declaração de uma
classe apenas para atender uma necessidade pontual no código.
l.bertholdo@ifsp.edu.br
Interface Runnable
• As threads também podem ser definidas por meio da interface
Runnable do pacote java.lang.
l.bertholdo@ifsp.edu.br
Interface Runnable
• A execução de threads criadas a partir da interface Runnable segue os
passos abaixo:
Passo Código de Exemplo
1. Definir a classe que implementa a interface Runnable public class Base implements Runnable {
e implementar o método run. @Override
public void run() {
// Código da thread
} }
2. Obter uma instância da classe que implementa a Base base = new Base();
interface Runnable.
3. Criar um objeto Thread por meio de um construtor // No método apropriado:
específico da classe Thread, o qual recebe como Thread thread1;
argumento uma referência do objeto Runnable. thread1 = new Thread(base, "base1");
l.bertholdo@ifsp.edu.br