programação orientada a objetos (dpadf 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf ·...

23
Programação Orientada a Objetos (DPADF 0063) Aula 10 Threads Universidade Federal de Santa Maria Colégio Agrícola de Frederico Westphalen Curso Superior de Tecnologia em Sistemas para Internet Prof. Bruno B. Boniati www.cafw.ufsm.br/~bruno

Upload: phamcong

Post on 16-Nov-2018

215 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Programação Orientada a Objetos (DPADF 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf · música, baixar vídeo) acontece de forma concorrente. ... execução independente,

Programação Orientada a Objetos

(DPADF 0063) Aula 10 – Threads

Universidade Federal de Santa Maria

Colégio Agrícola de Frederico Westphalen

Curso Superior de Tecnologia em Sistemas para Internet

Prof. Bruno B. Boniati – www.cafw.ufsm.br/~bruno

Page 2: Programação Orientada a Objetos (DPADF 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf · música, baixar vídeo) acontece de forma concorrente. ... execução independente,

Linhas de execução independentes

Page 3: Programação Orientada a Objetos (DPADF 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf · música, baixar vídeo) acontece de forma concorrente. ... execução independente,

Programação Concorrente

• Programar de forma concorrente significa pensar e escrever

programas de computador que fazem mais de uma coisa ao

mesmo tempo;

• Na vida real, muito do que fazemos (respirar, falar, ler, escutar)

e do que os computadores fazem (compilar, imprimir, tocar

música, baixar vídeo) acontece de forma concorrente.

• Os objetivos da programação concorrente podem ser:

▫ Reduzir o tempo total de processamento

▫ Aumentar a confiabilidade disponibilidade das aplicações

▫ Especializar serviços (SOs, simuladores), etc.

Page 4: Programação Orientada a Objetos (DPADF 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf · música, baixar vídeo) acontece de forma concorrente. ... execução independente,

Onde utilizar programação concorrente?

• Programação Reativa ▫ A aplicação responde a eventos de entrada (em uma GUI cada

evento corresponde a uma ação).

• Programação Interativa ▫ Escrever um programa dividindo tarefas: uma tarefa para fazer

alguma interação com o usuário, outra para exibir mensagens,

outra para fazer animação, etc...

• Paralelismo físico/distribuição ▫ Permite tirar vantagem de múltiplas CPUs centralizadas ou

distribuídas (cada vez mais presentes nos sistemas

computacionais).

Page 5: Programação Orientada a Objetos (DPADF 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf · música, baixar vídeo) acontece de forma concorrente. ... execução independente,

Threads

• Uma thread é uma linha de execução, um fluxo de execução,

um segmento de programa executando dentro da CPU;

• Programação multithreading consiste em pensar e escrever as

aplicações de forma que ações sejam executadas em paralelo

de forma concorrente;

• Apenas computadores com múltiplos processadores podem de

fato executar instruções em paralelo, porém, sistemas

operacionais modernos oferecem recursos para criar uma

“ilusão” de paralelismo em máquinas monoprocessadas

compartilhando o tempo de execução entre diferentes

aplicações.

Page 6: Programação Orientada a Objetos (DPADF 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf · música, baixar vídeo) acontece de forma concorrente. ... execução independente,

Threads (cont.)

• A figura abaixo demonstra a utilização da CPU por segmentos

de código. Observe que apenas um segmento ocupa a CPU de

cada vez e há uma fila de segmentos aguardando sua vez ...

Segmento

Segmento

Segmento

Segmento

Segmento

Segmento

Segmento

Segmento

CPU

Fila de

Segmentos

segmento

ganha a CPU

segmento deixa a CPU

Page 7: Programação Orientada a Objetos (DPADF 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf · música, baixar vídeo) acontece de forma concorrente. ... execução independente,

Programação concorrente & Java

• Java disponibiliza a concorrência de forma nativa por meio da

linguagem e de seu framework;

• Ao especificar uma thread estamos criando um fluxo de

execução independente, com sua própria pilha de chamadas de

método e contador de programa;

• Java inclui primitivos de multithreading de forma integrada à

linguagem de programação, não sendo necessário chamar

primitivas específicas do sistema operacional (isso é muito

importante para a portabilidade do código).

• A classe Thread representa um fluxo de execução

independente para a linguagem Java.

Page 8: Programação Orientada a Objetos (DPADF 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf · música, baixar vídeo) acontece de forma concorrente. ... execução independente,

Um pequeno exemplo ...

• Compile o código abaixo e o execute a classe resultante ...

public class Corrida extends Thread {

public Corrida(String n) {

super(n);

}

public void run() {

for (int i=1; i<=10; i++) {

System.out.println(getName() + " na volta " + i);

}

System.out.println("-->" + getName() + " chegou ");

}

public static void main (String args[]) {

Corrida s = new Corrida("Sebastian Vettel");

Corrida f = new Corrida("Fernando Alonso");

Corrida k = new Corrida("Kimi Raikkonen");

s.start();

f.start();

k.start();

}

}

Quem ganhou a corrida ? (execute novamente ... e agora, quem ganhou?)

O método run()

contém a tarefa que

a thread deve

executar. Quando

ele termina a thread

termina

O método start() coloca a thread

na fila para tentar ganhar CPU

Page 9: Programação Orientada a Objetos (DPADF 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf · música, baixar vídeo) acontece de forma concorrente. ... execução independente,

Métodos de uma thread

• getName()

▫ Cada thread pode opcionalmente ser identificada por um nome.

• setPriority(int prioridade)

▫ As threads podem ter prioridades distintas entre si (baixa, média e alta)

• sleep(long tempo)

▫ Faz com que a thread descanse por alguns milissegundos deixando

de ocupar a CPU. Ao acordar ela volta para a fila.

• start()

▫ Coloca a thread na fila para tentar ganhar CPU.

• yield()

▫ Retira a thread da CPU e já a recoloca na fila novamente (isso dá

chance de uma outra thread ganhar a CPU).

Page 10: Programação Orientada a Objetos (DPADF 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf · música, baixar vídeo) acontece de forma concorrente. ... execução independente,

Ciclo de vida de uma thread

running

(executando) sleeping

(dormindo)

waiting

(aguardando

algum recurso) runnable

(aguardando

na fila da CPU)

Monitor

Waiting

Dead

(Encerrada)

Page 11: Programação Orientada a Objetos (DPADF 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf · música, baixar vídeo) acontece de forma concorrente. ... execução independente,

O que leva a thread deixar a CPU?

• O objetivo de uma thread é alcançar a CPU para que possa ser

executada, mas há situações onde a thread deixa a CPU:

▫ Voluntariamente (através do método yield() para dar chance a outras

threads ocuparem o processador);

▫ Quando ela está aguardando algum recurso de IO (dados de arquivo,

entrada via teclado);

▫ Quando ela está aguardando lock de um recurso compartilhado;

▫ Por preempção (alguns SOs dão uma fatia de tempo para cada thread);

▫ Por prioridade (quando alguma thread de maior prioridade aparece na fila);

▫ Ao terminar sua tarefa (quando o método run() conclui).

Page 12: Programação Orientada a Objetos (DPADF 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf · música, baixar vídeo) acontece de forma concorrente. ... execução independente,

Prioridade de uma thread

• O modelo de escalonamento de Threads da JVM (a forma

como uma Thread é elegida para utilizar a CPU) é baseada em

prioridades.

• Existem 3 prioridades que podem ser utilizadas:

▫ Thread.MIN_PRIORITY (prioridade baixa)

▫ Thread.MAX_PRIORITY (prioridade alta)

▫ Thread.NORM_PRIORITY (prioridade normal)

• O método setPriority() é utilizado para indicar qual é a

prioridade da Thread.

Page 13: Programação Orientada a Objetos (DPADF 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf · música, baixar vídeo) acontece de forma concorrente. ... execução independente,

Prioridade de uma thread (cont.)

• A JVM elege as Threads de maior prioridade para ocupar a CPU em

detrimento das Threads de menor prioridade.

• Uma Thread de menor prioridade pode será executada quando as

Threads de maior prioridade

▫ terminarem

▫ executarem “yield()”

▫ executarem “sleep()”

▫ ficarem aguardando algum recurso bloqueado

• Se uma Thread de prioridade alta ocupar a CPU por muito tempo a

JVM pode selecionar, ocasionalmente, uma Thread de prioridade

mais baixa, “preemptando” a Thread de mais alta prioridade

Page 14: Programação Orientada a Objetos (DPADF 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf · música, baixar vídeo) acontece de forma concorrente. ... execução independente,

Interface Runnable

• Criar uma classe descendente de Thread nem sempre é uma

boa ideia, principalmente em Java, onde cada classe tem uma

única superclasse.

• A classe Thread disponibiliza alguns métodos estáticos que

recebem objetos de classes que implementam uma interface

específica ... Runnable

• A interface Runnable exige basicamente a implementação do método run().

Page 15: Programação Orientada a Objetos (DPADF 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf · música, baixar vídeo) acontece de forma concorrente. ... execução independente,

Interface Runnable (cont) class Tarefa implements Runnable {

String nome;

public Tarefa (String n) {

nome = n;

}

public void run() {

for (int i=0; i<10; i++)

System.out.println(nome + " executando tarefa (" + i + ")");

System.out.println(nome + " concluído ");

}

public static void main(String args[]) {

Tarefa t1 = new Tarefa("t1");

Tarefa t2 = new Tarefa("t2");

new Thread(t1).start();

new Thread(t2).start();

}

}

A interface Runnable

exige o método run()

Uma nova Thread é instanciada

passando como parâmetro um objeto de uma classe Runnable

Page 16: Programação Orientada a Objetos (DPADF 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf · música, baixar vídeo) acontece de forma concorrente. ... execução independente,

Sincronização (Imagine o seguinte cenário)

• Uma classe conta bancária com métodos para obter e

atualizar o saldo;

public class Conta {

public double saldo = 0;

public Conta(double saldo) {

this.saldo = saldo;

System.out.println("Saldo inicial: R$" + saldo);

}

public double getSaldo() {return saldo;}

public void setSaldo(double saldo) {this.saldo = saldo;}

}

Page 17: Programação Orientada a Objetos (DPADF 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf · música, baixar vídeo) acontece de forma concorrente. ... execução independente,

Sincronização (cont.) (Imagine o seguinte cenário)

• Um classe banco com dispositivos para

movimentar as contas;

public class Banco {

public boolean saque(Conta conta, double valor) {

double saldo = conta.getSaldo();

if (saldo < valor) {

System.out.println("Saldo insuficiente para o saque.");

return false;

}

double novoSaldo = saldo - valor;

System.out.println(Thread.currentThread().getName() +

" sacou R$" + valor +

". Saldo após saque: R$" + novoSaldo);

conta.setSaldo(novoSaldo);

return true;

}

}

Page 18: Programação Orientada a Objetos (DPADF 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf · música, baixar vídeo) acontece de forma concorrente. ... execução independente,

Sincronização (cont.) (Imagine o seguinte cenário)

• Uma classe cliente de um banco com sua conta corrente,

um valor para saque e a vontade de gastar todo o dinheiro;

public class Cliente extends Thread {

private static Banco banco = new Banco();

private Conta conta = null;

private double valor = 1000;

public Cliente(String nome, Conta conta) {

super(nome);

this.conta = conta;

}

public void run() {

double total = 0;

while (banco.saque(conta,valor))

total += valor;

System.out.println(getName() + " sacou total de R$" + total);

}

}

Page 19: Programação Orientada a Objetos (DPADF 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf · música, baixar vídeo) acontece de forma concorrente. ... execução independente,

Sincronização (cont.) (Imagine o seguinte cenário)

• Várias instâncias de clientes (uma família) movimentando

uma mesma conta ao mesmo tempo.

public class Familia {

public static void main (String args[]) {

final Conta conta = new Conta(100000);

Cliente pai = new Cliente("Pai ", conta);

Cliente mae = new Cliente("Mãe ", conta);

Cliente filho = new Cliente("Filho", conta);

pai.start();

mae.start();

filho.start();

}

}

Page 20: Programação Orientada a Objetos (DPADF 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf · música, baixar vídeo) acontece de forma concorrente. ... execução independente,

Sincronização (cont.) (Observe a execução da classe família)

Saldo inicial: R$10000.0

Pai sacou R$1000.0. Saldo após saque: R$9000.0

Filho sacou R$1000.0. Saldo após saque: R$9000.0

Mãe sacou R$1000.0. Saldo após saque: R$9000.0

Filho sacou R$1000.0. Saldo após saque: R$8000.0

Pai sacou R$1000.0. Saldo após saque: R$8000.0

Filho sacou R$1000.0. Saldo após saque: R$7000.0

Mãe sacou R$1000.0. Saldo após saque: R$8000.0

Filho sacou R$1000.0. Saldo após saque: R$6000.0

Pai sacou R$1000.0. Saldo após saque: R$7000.0

Filho sacou R$1000.0. Saldo após saque: R$5000.0

Mãe sacou R$1000.0. Saldo após saque: R$7000.0

Filho sacou R$1000.0. Saldo após saque: R$4000.0

Pai sacou R$1000.0. Saldo após saque: R$6000.0

Filho sacou R$1000.0. Saldo após saque: R$3000.0

Mãe sacou R$1000.0. Saldo após saque: R$6000.0

Filho sacou R$1000.0. Saldo após saque: R$2000.0

Pai sacou R$1000.0. Saldo após saque: R$5000.0

Filho sacou R$1000.0. Saldo após saque: R$1000.0

Mãe sacou R$1000.0. Saldo após saque: R$5000.0

Filho sacou R$1000.0. Saldo após saque: R$0.0

Pai sacou R$1000.0. Saldo após saque: R$4000.0

Saldo insuficiente para o saque.

Mãe sacou R$1000.0. Saldo após saque: R$4000.0

Filho sacou total de R$10000.0

Pai sacou R$1000.0. Saldo após saque: R$3000.0

Mãe sacou R$1000.0. Saldo após saque: R$3000.0

Pai sacou R$1000.0. Saldo após saque: R$2000.0

Mãe sacou R$1000.0. Saldo após saque: R$2000.0

Pai sacou R$1000.0. Saldo após saque: R$1000.0

Mãe sacou R$1000.0. Saldo após saque: R$1000.0

Pai sacou R$1000.0. Saldo após saque: R$0.0

Saldo insuficiente para o saque.

Mãe sacou R$1000.0. Saldo após saque: R$0.0

Saldo insuficiente para o saque.

Pai sacou total de R$10000.0

Mãe sacou total de R$10000.0

Saldo inicial R$ 10.000,00

Saldo insuficiente para o saque

Mãe sacou R$ 1000,00 (saldo após o saque R$ 3 mil)

Quanto cada um sacou até que o saldo acabasse?

Filho sacou total de R$ 10000

Pai sacou total de R$ 10000

Mãe sacou total de R$ 10000

Page 21: Programação Orientada a Objetos (DPADF 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf · música, baixar vídeo) acontece de forma concorrente. ... execução independente,

Sincronização (cont.)

• O código executado anteriormente utiliza um recurso compartilhado entre

todas as Threads (objeto da classe Conta);

• Para garantir acesso exclusivo a um recurso compartilhado, ou seja, criar

uma fila de espera para utilizar o recurso um de cada vez, faz-se necessário

utilizar recursos de sincronização.

• A palavra reservada synchronized marca um método ou um bloco de

código como sincronizado, isso garante que aquele código somente será

acessado por uma Thread de cada vez.

• Experimente alterar a interface dos métodos abaixo incluindo a palavra synchronized:

Conta.getSaldo()

Conta.setSaldo(double)

Banco.saque(Conta, double)

Page 22: Programação Orientada a Objetos (DPADF 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf · música, baixar vídeo) acontece de forma concorrente. ... execução independente,

Exercícios para fixação

Page 23: Programação Orientada a Objetos (DPADF 0063)bruno/disciplinas/poo/slides/aula10_threads.pdf · música, baixar vídeo) acontece de forma concorrente. ... execução independente,

Corrida Maluca...

• Codifique uma classe veículo que implementa a interface runnable.

• A cada corrida, cada veículo possui uma velocidade que é sorteada quando a

classe é instanciada.

• Simule uma corrida maluca com os personagens do desenho animado

Wacky Races (produzido nos estúdios Hanna-Barbera nos anos de 68 e 70).

• Utilize todos os personagens (Dick Vigarista & Muttley, Irmãos Rocha,

Cupê Mal-Assombrado, Professor Aéreo, Barão Vermelho, Penélope Charmosa,

Carro Tanque, Quadrilha de Morte, Peter Perfeito e Rufus Lenhador)