Você está na página 1de 44

Multithreading ou Execuo Concorrente

Vida real: processos ocorrem simultaneamente (respiramos, pensamos, comemos, corao bate, andamos, o sangue circula...) Computadores:
Executam processos concorrentes; At agora s sabemos programar sequencialmente

Multithreading ou Execuo Concorrente


Linguagens de programao com suporte multiprocessamento:
ADA (governo USA) CHILL (sistemas de telefonia) C/C++ (com bibliotecas de apoio) Java ()

Multithreading ou Execuo Concorrente


Multithreading em Java
Usos: comunicao via rede, comunicao entre processos, problemas tipo produtor-consumidor Difcil: no h metodologia simples de modelar problemas de concorrncia. API j implementada em Java. Gerencia a concorrncia para o programador (oba!) Vrios objetos prontos Devemos usar o que est pronto sempre que possvel!

Threads - Conceitos Bsicos


O que uma thread? Fluxo seqencial de controle dentro de um processo. Conjunto de todos os estados necessrios para um processamento. O suporte a mltiplas linhas de execuo permite que mltiplos processamentos ocorram em "paralelo" (em computadores com um processador, os threads no so executados em paraleloconcorrentemente).

Threads - Conceitos Bsicos


Queremos escrever programas que possam fazer vrias tarefas simultaneamente.
baixar uma imagem pela rede. requisitar um relatrio atualizado do estoque. rodar vrias animaes. tudo ao mesmo tempo.

Cada thread representa a execuo de uma sequncia de comandos independentes.

Estados de uma Thread

Threads - Conceitos Bsicos


Vrias threads em vrias CPUs
Tarefa 1 Tarefa 2

Tarefa 3

Vrias threads compartilhando uma nica CPU

Tarefa 1 Tarefa 2 Tarefa 3

Threads - Conceitos Bsicos

Threads em Java
Suporte a multithreading faz parte da linguagem.
Todo programa executado em pelo menos uma thread.
class UmaUnicaThread { public static void main(String[] args) { // main() executado em um nica thread System.out.println(Thread.currentThread()); for (int i=0; i<30; i++) System.out.println("i == " + i); } }

Exemplo
Thread[main,5,main] i == 0 i == 1 i == 2 i == 3 i == 4 i == 5 i == 6 i == 10 i == 20 i == 11 i == 21 i == 12 i == 22 ... i == 29

Exemplo
class CountThread extends Thread O mtodo run( ) como { int from, to; se fosse um main( ), public CountThread(int from, int to) s que no esttico { this.from = from; this.to = to; } public void run() { for (int i=from; i<to; i++) System.out.println("i == " + i); } public static void main(String[] args) { // Dispara 5 threads, cada uma ir contar 10 vezes for (int i=0; i<5; i++) { CountThread t = new CountThread(i*10, (i+1)*10); t.start(); } } }

Exemplo
class CountThread extends Thread { int from, to; public CountThread(int from, int to) { this.from = from; this.to = to; } public void run() Iniciar uma thread ir criar { for (int i=from; i<to; i++) uma nova sequncia de System.out.println("i == " + i); controle e chamar o mtodo } run( ) da thread public static void main(String[] args) { // Dispara 5 threads, cada uma ir contar 10 vezes for (int i=0; i<5; i++) { CountThread t = new CountThread(i*10, (i+1)*10); t.start(); } } }

Exemplo
class CountThread extends Thread Thread uma { int from, to; classe em Java! public CountThread(int from, int to) { this.from = from; this.to = to; } public void run() { for (int i=from; i<to; i++) System.out.println("i == " + i); } public static void main(String[] args) { // Dispara 5 threads, cada uma ir contar 10 vezes for (int i=0; i<5; i++) { CountThread t = new CountThread(i*10, (i+1)*10); t.start(); } } }

Exemplo
main 0..9 10..19 20.29 30..39 40..49

Exemplo
1a. Execuo i == 0 i == 1 i == 2 i == 3 i == 4 i == 5 i == 6 i == 10 i == 20 i == 11 i == 21 i == 12 i == 22 ... 2a. Execuo i == 0 i == 1 i == 2 i == 3 i == 4 i == 10 i == 20 i == 11 i == 21 i == 31 i == 41 i == 5 i == 6 ...

Threads API
Thread()
Classe Thread possibilita a criao de um objeto executvel.

void run()
invocado pelo sistema de execuo da JVM. deve-se sobrescrever este mtodo (polimorfismo por sobreposio) para prover o cdigo a ser executado pela thread.

void start()
inicia a thread e provoca a chamada de run().

void stop()
pra a execuo da thread.

void suspend()
suspende a execuo da thread.

void resume()
retoma a execuo interrompida por um suspend().

Threads API
static void sleep(long millis) throws InterruptedException
pe a thread para dormir por um tempo em milisegundos.

void interrupt()
interrompe a thread em execuo.

static boolean interrupted()


testa se a thread foi interrompida.

Threads API
boolean isAlive()
testa se a thread est rodando.

void setPriority(int p)
define a prioridade de execuo da thread.

void yield()
indica ao gerenciador de threads que esta uma boa hora para rodar outras threads.

void join()
espera que uma thread termine sua execuo.

Estados

Estados
Uma thread finalizada:
atravs dos mtodos stop() ou destroy(). ao terminar a execuo do mtodo run().
algumas threads podem continuar rodando mesmo aps a finalizao do run().

se estiver associada a outra thread, terminar juntamente com ela. minhaThread.setDeamon(true).

Threads de Usurio x Deamons


Uma thread do tipo deamon roda sempre como um pano de fundo da thread que a criou.
uma thread deamon termina quando a thread que a criou tambm terminar.

Uma thread que no uma deamon chamada de thread de usurio. Em Java, um programa permanece em execuo enquanto ele possuir pelo menos uma thread no daemon executando. Quando s existem threads do tipo daemon rodando, o programa finalizado.

Threads de Usurio x Deamons


...main(...)... thread1.setDeamon(true); thread1.start(); thread2.setDeamon(true); thread2.start(); thread3.start(); return; Sero automaticamente finalizadas quando o mtodo main( ) for finalizado

Pode continuar a execuo mesmo aps o final de main( )

Uma Classe Executvel


Geralmente no conveniente criar uma subclasse de Thread.
tambm no ser possvel devido ao mecanismo de herana implementado em Java.

A interface Runnable adiciona o mtodo run() sem herdar nada de Thread. (Melhor!)
public interface Runnable { public void run(); }

Exemplo
/* Programa Java que dispara threads */ class CountThreadRun implements Runnable { int from, to; public CountThread(int from, int to) { this.from = from; this.to = to; } public void run() { for (int i=from; i<to; i++) System.out.println("i == " + i); } }

Exemplo
Para executar como uma thread:
// Cria uma instncia de Runnable Runnable r = new CountThreadRun(10,20); // Cria uma instncia de Thread Thread t = new Thread(r); // inicia a execuo da thread t.start();

Exemplo - MultiplaImpressao
/* Este programa cria uma classe chamada MultiplaImpressao*/ public class MultiplaImpressaoThread implements Runnable { Thread threadDaClasse; String string; int contador; int tempoDormindo; /* mtodo construtor da classe */ public MultiplaImpressaoThread (String s, int quantasVezes, int dormir) { contador = quantasVezes; string = s; tempoDormindo = dormir; threadDaClasse = new Thread (this); threadDaClasse.start(); } /*Fim do metodo construtor

Exemplo - MultiplaImpressao
public void run () {
while (contador > 0) { System.out.println (string); try { Thread.sleep (tempoDormindo); } catch (Exception e) { } } /*fim-while */

} /* Fim do metodo run */ public static void main (String args[]) {


new MultiplaImpressaoThread (ping", 5, 300); new MultiplaImpressaoThread (pong", 5, 500);

} /* Fim do metodo main */ } /* Fim da classe MultiplaImpressaoThread */

Exemplo (2)
class MeuApplet extends Applet implements Runnable { private Thread timer = null; public void init() { timer = new Thread(this); timer.start(); } ... public void run() { ... } }

Exemplo Relogio Digital


import java.awt.Graphics; import java.awt.Font; import java.util.Date; public class RelogioDigitalThreads extends java.applet.Applet implements Runnable { Font aFonte = new Font("TimesRoman",Font.BOLD,24); Date aData; Thread runner; public void start() { if (runner == null) { runner = new Thread(this); runner.start(); } } public void stop() { if (runner != null) { runner.stop(); runner = null; } }

Exemplo Relogio Digital


public void run() { while (true) { aData = new Date(); repaint(); try { Thread.sleep(1000); } catch (InterruptedException e) {} } } public void paint (Graphics g) { g.setFont(aFonte); g.drawString(aData.toString(),10,50); } }

Exemplo Relogio Digital


http://www.cria.org.br/~bene/PA2/teste.html

Construtores
public public public public public Thread(); Thread(Runnable target); Thread(String name); Thread(Runnable target, String name); Thread(ThreadGroup group, Runnable target); public Thread(ThreadGroup group, String name); public Thread(ThreadGroup group, Runnable target, String name);

Escalonamento em Java
Mecanismo que determina como os threads executveis (runnable) iro utilizar tempo de CPU.
Preemptiva. filas de prioridades. no h diviso de tempo entre as filas (time sliced).

threads com menor prioridade podem ser executadas quando as de maior prioridade no estiverem rodando.
sleep(), yield(), stop()

Prioridade
Cada thread apresenta uma prioridade de execuo.
pode ser alterada com setPriority(int p) pode ser lida com getPriority()

Algumas constantes incluem:


Thread.MIN_PRIORITY Thread.MAX_PRIORITY Thread.NORM_PRIORITY o padro Thread.NORM_PRIORITY

Agrupando Threads
Pode-se operar as threads como um grupo.
pode-se parar ou suspender todas as threads de uma s vez.

group.stop();

ThreadGroup g = new ThreadGroup("um grupo de threads");

Agrupando Threads
Inclua uma thread em um grupo atravs do construtor da thread.
Thread t = new Thread(g,new ThreadClass(), "Esta thread");

Agrupando Threads
Para saber quantas threads em um grupo esto sendo executadas no momento, podemos usar o mtodo activeCount():
System.out.println("O nmero de threads "+ " que podem estar rodando "+ g.activeCount());

Sincronizao
Considere o seguinte cdigo:
public class Contador { private int conta = 0; public int incr() { int n = conta; conta = n + 1; return n; } }

Sincronizao
O que acontece caso tenhamos duas threads que iro executar o mesmo cdigo a seguir?
Ambas as threads esto acessando o mesmo objeto.

int cnt = Contador.incr();

Situao 1

Thread 1 cnt = Contador.incr(); n = conta; conta = n + 1; return n; ---------

Thread 2
--------cnt = Contador.incr(); n = conta; conta = n + 1; return n;

count 0 0 1 1 1 1 2 2

Situao 2

Thread 1 cnt = Contador.incr(); n = conta; --------conta = n + 1; return n;

Thread 2
----cnt = Contador.incr(); n = conta; conta = n + 1; return n; -----

count 0 0 0 0 1 1 1 1

Monitores
public class Contador2 { private int conta = 0; public synchronized int incr() { int n = conta; conta = n + 1; No permite que este return n; mtodo seja executado } por mais de uma thread } ao mesmo tempo

Monitores
Tambm podemos usar monitores para partes de um mtodo.
synchronized(oObjeto) sentena; // Sincronizada em relao a oObjeto

Indique o recurso a ser monitorado

Monitores
void metodo(UmaClasse obj) { synchronized(obj) { obj.variavel = 5; } }

Ningum poder usar este objeto enquanto estivermos executando estas operaes