Você está na página 1de 22

Threads em Java

Prof. Guilherme C. Kurtz

Conforme vimos na aula passada, uma thread pode ser implementada:


Pelo prprio sistema operacional Por uma biblioteca;

A linguagem Java fornece o suporte a threads ao nvel de programao; O mtodo main() a principal thread na execuo de uma aplicao Java.

Uma forma de criar threads em java criar uma classe derivada (extends) da classe Thread, e redefinir o mtodo run() dessa classe;
Um objeto dessa classe executar como uma thread de controle separado na mquina virtual;

A criao do objeto derivado da classe Java s especifica a thread;


A criao e inicializao da thread fica por conta do mtodo start(); O mtodo start()aloca memria e inicializa uma nova thread na mquina virtual;

class MinhaThread extends Thread{ public void run(){ System.out.println("Ol, sou a thread criada"); } }
public class MinhaApp{ public static void main(String args[]){ MinhaThread t = new MinhaThread(); t.start(); System.out.println("Ol, sou a thread principal"); } }

Uma outra forma de implementar uma thread definir uma classe com a interface Runnable; Quando uma classe implementa Runnable, novamente dever ser definido o mtodo run() e implement-lo da mesma forma anterior;
A nica diferena acontecer quando for criada a thread, conforme pode ser visto no cdigo a seguir.

class MinhaRunnable implements Runnable{ public void run(){ System.out.println("Ol, sou a thread criada"); } } public class MinhaApp2{ public static void main(String args[]){ Runnable runner = new MinhaRunnable(); Thread t = new Thread(runner); t.start(); System.out.println("Ol, sou a thread principal"); } }

extends Thread ou implements Runnable?


A princpio, utilizar extends Thread mais simples; Porm, se for necessrio extender alguma outra classe, no ser possvel, pois java no suporta mltipla herana; Ao utilizar Runnable, a classe poder extender outra classe, visto que neste casso estaremos implementando e no extendendo.

Antes da chamada ao mtodo t.start()

Antes de realizar a chamada a este mtodo, a thread est no estado novo;

Ns temos o objeto thread, mas ainda no temos uma thread real, pois no foi colocada em execuo;

Aps a chamada ao mtodo start()


Uma nova thread de execuo iniciada; A thread passar do estado novo para o estado executvel;
Quando a thread executada, o mtodo run() executado.

O comportamento das threads no garantido, pois a documentao java no fala nada a respeito sobre a ordem de execuo das threads;
Tambm no h garantias de que, uma vez iniciada, ela ser concluda;

A ordem de inicializao no afeta a ordem de execuo; Uma thread deixar de ser thread quando o seu mtodo run() concludo;
Uma thread jamais poder ser reinicializada, ou seja, se for feita uma chamada ao start() novamente, ser gerada uma exceo.

Para gerenciar as threads, a linguagem Java oferece uma srie de mtodos;


Mtodos de Suspenso:
suspend()
Suspente a execuo de uma thread que estiver em processamento naquele momento;
Suspende a execuo de uma thread por um determinado perodo de tempo (em milissegundos); Retorna a execuo de uma thread que foi suspensa; Interrompe permanentemente a execuo de uma thread;

sleep(long millis)

resume() stop()

//Sleep utilizando extends Thread class ExemploSleep extends Thread { public void run() { System.out.println("Ol, sou a thread e vou dormir por 5s"); try{ sleep(5000); System.out.println("Acordei"); }catch(Exception e){ e.printStackTrace(); } } }
public class MinhaApp3 { public static void main(String args[]) { ExemploSleep t = new ExemploSleep(); t.start(); } }

//Sleep utilizando implements Runnable class ExemploSleepRunnable implements Runnable { public void run() { System.out.println("Ol, sou a thread e vou dormir por 5s"); try{ Thread.sleep(5000); System.out.println("Acordei"); }catch(Exception e){ e.printStackTrace(); } } }
public class MinhaApp3 { public static void main(String args[]) { Runnable runner = new ExemploSleepRunnable(); Thread t = new Thread(runner); t.start(); } }

Prioridade de threads:
As prioridades em threads indicam quanto recurso deve ser dado a determinada thread; Portanto, uma thread com alta prioridade receber mais tempo de CPU que uma thread de baixa prioridade; Para isso, existe o mtodo setPriority(int newPriority)que define a prioridade de determinada thread.

Prioridade de threads:
setPriority(int newPriority)
A prioridade vai de 1 a 10, sendo o valor padro 5; Quanto maior o valor, maior a prioridade; Alm disso, existem as constantes:
Thread.MAX_PRIORITY que vale 10; Thread.MIN_PRIORITY que vale 1; Thread.NORM_PRIORITY que vale 5;

getPriority()
Retorna a prioridade daquela thread;

class ExemploPrioridade extends Thread{ String nome;

public void setNome(String s){ this.nome = s; } public void run() { int count=0; while(true){ try{ sleep(100); }catch(Exception e){ e.printStackTrace(); } System.out.println(nome+":" +count++); } } }

public class MinhaApp5{ public static void main(String args[]){ ExemploPrioridade t1 = new ExemploPrioridade(); t1.setNome("Thread 1"); t1.setPriority(10); ExemploPrioridade t2 = new ExemploPrioridade(); t2.setNome("Thread 2"); t2.setPriority( Thread.MIN_PRIORITY); t2.start(); t1.start(); } }

Prioridade de threads:
Mtodo yield():
Faz com que uma thread passe do estado executando para executvel/esperando;

passa a CPU para outra thread a fim de que outras threads com outras prioridades tenham sua oportunidade de executar;

class ExemploYield extends Thread{ String nome; public void setNome(String s){ this.nome = s;} public void run() { while(true){ System.out.println(nome+ com prioridade "+getPriority()); if(this.nome.equals("Thread 1")){ System.out.println("Sou a thread 1 e vou descansar um pouco"); yield(); }}}} public class MinhaApp6{ public static void main(String args[]){ ExemploYield t1 = new ExemploYield(); t1.setNome("Thread 1"); t1.setPriority(10); ExemploYield t2 = new ExemploYield(); t2.setNome("Thread 2"); t2.setPriority(Thread.MIN_PRIORITY); t2.start(); t1.start(); }}

Sincronizao de threads
Quando duas ou mais threads precisam utilizar ao mesmo tempo um objeto, existe a possibilidade de haver uma corrupo dos dados; As sees/mtodos/blocos destes programas que possuem tais dados so denominados sees crticas; Para solucionar este problema, necessrio sincronizar estas regies atravs de monitores ou locks, para que somente uma thread possa utilizar um recurso por vez;

Sincronizao de threads
possvel sincronizar mtodos: public synchronized void Sacar(int valor){ ... }
Ou blocos de mtodos:
public void Sacar(int valor){ synchronized(this){ ... } }

Interao entre threads

A linguagem Java inclui trs importantes mtodos que permitem que uma thread sinalize algo para outra; Estes mtodos so se grande importncia em aplicaes concorrentes;

Mtodo wait(): Faz com que a thread em questo fique suspensa, dizendo para ela esperar at que alguma outra thread diga que ela possa voltar a executar; Mtodo notify(): Este mtodo notifica alguma outra thread dizendo para ela que ela pode acordar e voltar a executar;

Interao entre threads


Mtodo notifyAll():
Mesma idia do anterior, s que ao invs de notificar uma thread, notifica todas.

Ps: quando utilizamos o notify(), somente uma thread avisada, mas no temos garantia de saber qual ser. Isso vai depender da implementao.

Ps2: o notifyAll() avisa todas as threads, logo, possivelmente aquela thread com maior prioridade ser liberada para execuo.

Você também pode gostar