O Mecanismo de Threads em Java 2 - Dei-Isep

Propaganda
O Mecanismo de
Threads
em Java 2
Criar uma classe herdeira da
super classe Thread
public class minhaThread extends Thread{
}
Re-escrever o método
run( )
public class minhaThread extends Thread{
public void run( ){
...
}
}
Criar uma classe Teste
e criar um objecto
public class TesteMinhaThread {
minhaThread mt ;
mt = new minhaThread(“Apresentação em LP2”) ;
}
Iniciar a thread implantada
public class TesteMinhaThread {
minhaThread mt = new minhaThread() ;
mt.start( ) ;
mt.run( ) ;
}
Um exemplo:
public class minhaThread extends Thread{
private static final int REPETICOES = 10;
private static final int ATRASO=1000;
private String mensagem;
public minhaThread(String msg){
mensagem = msg;
}
public void run(){
try{
for(int i=1; i<= REPETICOES; i++){
System.out.println( mensagem );
sleep(ATRASO);
}
}
catch(InterruptedException ie){
}
}
}
O resultado seria: um output da mansagem:
“Apresentação em LP2”
uma vez por segundo, 10 vezes
Apresentação em LP2
Apresentação em LP2
Apresentação em LP2
Apresentação em LP2
Apresentação em LP2
Apresentação em LP2
Apresentação em LP2
Apresentação em LP2
Apresentação em LP2
Apresentação em LP2
O interface Runnable
Java dispõe de uma interface Runnable
O procedimento para criação de objectos é o quase o mesmo:
public class MeuRunnable implements Runnable
Implementa-se o método run( ) que está declarado na interface
Runnable como método abstracto.
Quando construímos numa classe teste um objecto do género
MeuRunnable os métodos de Thread são invocados com o nome
da classe. Por exemplo:
Thread.start( ) ;
A razão para de ser deste interface tem a ver com a hierarquia.
Como Java não implementa a herança múltipla sempre que
fosse necessário colocar uma thread a nossa classe teria
obrigatoriamente que ser herdeira da classe Thread.
O método de classe Thread.start( ) vai executar o método run( )
na classe que implementa a interface Runnable.
Agenda de Threads
A J.V.M. dispõe de uma agenda para conter as threads, mas…
escolhe a thread a executar de uma forma aleatória!!
 cada thread corre num curto espaço de tempo, chamado de
‘time-slice’
 uma thread está à disposição da agenda se não estiver em
modo sleep( )
RESUMO: as várias threads que estejam iniciadas - pelo método
start( ) – vão ser executadas de forma aleatória
Prioridades
Podem atribuir-se diferentes prioridades às várias threads através
do método setPriority( ) ;
Valor
(inteiro)
0
Atributo
estático
Thread.MIN_PRIORITY
5
Thread.NORM_PRIORITY
10
Thread.MAX_PRIORITY
(defeito)
se for introduzido um valor fora do intervalo 0 – 10 é atirada uma
excepção IllegalArgumentException
a agenda de threads escolhe sempre para executar a que tiver valor
mais elevado
se existir mais do que uma thread com a mesma prioridade (mesmo
que prioridades elevadas) é escolhida uma aleatoriamente
se uma thread com prioridade elevada acorda enquanto outra thread
com prioridade inferior está em execução, esta última é suspensa e a
thread com maior prioridade é executada.
RESUMO: apesar de parecerem bastante úteis, as prioridades não devem
ser utilizadas devido à re-utilização de código (uma das características
da P.O.O.).
Terminar as Threads
uma thread termina quando o método run( ) retorna
se duas ou mais threads estiverem a resolver o mesmo
problema e, se uma encontrar a solução, é necessário notificar
as outras para terminarem. Usa-se o método interrupt( )
para se verificar se o estado de uma thread foi alterado pode
usar-se o método isInterrupted( )
Na classe MinhaThread por exemplo, o método run( ) podia ter sido
escrito da seguinte forma:
public void run(){
try{
for( int i=1;
i <= REPETICOES && ! isInterrupted( );
i++){
System.out.println( mensagem );
sleep(ATRASO);
}
}
catch(InterruptedException ie){
}
}
Grupos de Threads
No caso de existirem várias threads estas podem ser declaradas
como pertencentes a um grupo
String nome = “NomeGrupo”
ThreadGroup group = new ThreadGroup( nome ) ;
As threads sao geridas em sumultâneo. No caso de ser
necessário notificar todas para pararem basta escrever:
group.interrupt( ) ;
Quando um utilizador de uma página web decide que já não
quer carregar mais essa página, o programa pode terminar todas
as threads em simultâneo.
Sincronização
Duas ou mais threads podem partilhar o acesso ao mesmo
objecto.
O acesso partilhado pode provocar um problema que é
conhecido como Race Condition.
A finalidade do objecto fica depende da thread que vence a
competição.
Para se resolver esta situação deve-se sincronizar os métodos
que alteram o estado de um objecto e que contenham threads.
Sincronização de Acesso a um
Objecto
Deve marcar-se um método com a palavra reservada
synchronized.
public class NumEncomendas{
public void synchronized AnularEncomenda( ){
…
}
}
Cada objecto tem uma fechadura. Por defeito, esta está
“destrancada”.
Quando uma thread acciona um método “tranca” a fechadura
desta
Quando uma outra thread tenta aceder a um método
sincronizado tem que aguardar que a thread “destranque” o
objecto. Não lhe pode aceder.
Duas ou mais threads podem aguardar o “destrancar” de um
objecto. A thread que a seguir tem o acesso ao objecto é
escolhido conforme a prioridade e, em caso de igualdade de
prioridades, é escolhida uma thread aleatoriamente.
Download