Programação Concorrentecom Thread Java
Luiz Affonso GuedesSistemas Distribuidos
Definições Básicas• Threads são sub-procesos no sistema
operacional.• É menos custoso gerenciar threads do que
processos.• As linguagens Java e Ada possuem
funcionalidades MULTITHREADING na própriaestrutura da linguagem.
• C e C++ necessitam de biblioteca especificapara processamento MULTITHREADING – Posix p_thread
Thread em Java
• Em Java, threads são implementadascomo uma CLASSE– Pacote java.lang.Thread– É uma extensão da classe Thread– Contrutores:
• public Thread (String nome_da_thread);• public Thread ( ); // o nome sera Thread-#
» Thread-1, Thread-2,…
Principais Métodos– run(): é o método que executa as
atividades de uma THREAD. Quandoeste método finaliza, a THREAD tambémtermina.
– start(): método que dispara a execução de uma THREAD. Este método chama o método run( ) antes de terminar.
– sleep(int x): método que coloca aTHREAD para dormir por x milisegundos.
Principais Métodos
– join( ): método que espera o término daTHREAD para qual foi enviada a mensagempara ser liberada.
– interrupt( ): método que interrompe a execução de uma THREAD.
– interrupted( ): método que testa se umaTHREAD está ou não interrompida.
Estados de uma Thread em Javanascimento
pronta
executando
esperando dormindo morta bloqueada
start( )
Alocar um processador
wait( )sleep( ) Fim do
Método run( )
E/S
Fim da E/Snotify( )
notifyAll( )
Término do tempo de dormida
run( )
Prioridade de Thread
• Em Java, a prioridade é determinada com um inteiro entre 1 e 10.
• A prioridade padrão é o valor 5.• 10 é a maior prioridade e 1 é a menor.• A THREAD herda a prioridade da
THREAD que acriou.• void setPriority(int prioridade);• int getPriority( );
Algoritmo de EscalonamentoPrioridade 10
Prioridade 1
Prioridade 9
Prioridade 8
Prioridade 2
Prioridade 3
.
.
.
A B
C
D E F
G
Exemplo 01
• O programa cria 04 threads e as colocapara dormir.
• ThreadBasica é uma extensão da classeThread.
Exemplo 1 – Thread01.javapublic class Thread01 {
// criacao e start das threads
public static void main( String args[] )
{
System.out.println("Main: Inicio da Thread main()\n");
// Declaracao de quatro objetos do tipo ThreadBasica
ThreadBasica thread1, thread2, thread3, thread4;
// criacao de quatro objetos do tipo ThreadBasica
thread1 = new ThreadBasica( "thread1" );
thread2 = new ThreadBasica( "thread2" );
thread3 = new ThreadBasica( "thread3" );
thread4 = new ThreadBasica( "thread4" );
System.err.println( "\nMain: Disparando as threads" );
thread1.getReferenciaThread(thread2);
// start de execucao das quadro Threads
thread1.start();
thread2.start();
thread3.start();
thread4.start();
System.err.println( "Main:Threads Basicas iniciadas\n" );
try{
thread1.join();
thread2.join();
thread3.join();
thread4.join();
}
catch(InterruptedException x) { }
System.out.println("Main: Agora faça o modelo em Rede de Petri desse programa\n");
System.out.println("Main: Fim da Thread main()\n");
} // --- fim do metodo main()
} // --------- fim da classe Thread01
ThreadBasica.java// metodo que ira fazer a execucao da thread
public void run()
{ // escreve que a thread ira dormir
try {
System.err.println( getName() + " vai comecar a dormir" );
//Thread.sleep( tempo_de_sono );
sleep(tempo_de_sono);
//this.sleep(tempo_de_sono);
}
// tratamento de erro caso haja algum erro durante o processo de sono da thread
catch ( InterruptedException interruptedException ) {
System.err.println( interruptedException.toString() );
}
if(namorada != null) {
try{ namorada.join(); }
catch(InterruptedException x) { }
}
// escreve o nome da thread apos o termino de seu sono
System.err.println( getName() + " acordou e agora vai morrer" );
} /
} // ----------- fim da classe ThreadBasica
// Classe ThreadBsica estende a classe Thread
// Cada objeto desta classe ira dormir aleatoriamente entre 0 e 5 segundos.
class ThreadBasica extends Thread {
private int tempo_de_sono;
private ThreadBasica namorada = null;
// construtor recebe o nome da thread
// ele chama o construtor da classe pai (super)
public ThreadBasica( String nome ) {
super( nome ); // construtor da classe pai
// determina o tempo do sono aleatoriamente entre 0 e 5s
tempo_de_sono = (int) ( Math.random() * 5000 ); //metodo estatico da classe Math
// escreve o nome da thread e seu tempo de sono
System.err.println(
"Nome: " + getName() + "; tempo do sono: " + tempo_de_sono );
}
void getReferenciaThread(Thread t1) {
namorada = (ThreadBasica) t1;
}
Exercício 01
– Analise como se chama o método sleep().– Crie n THREADs, onde n é definido pelo
usuário.– Utilize o método join no main para esperar as
THREADs terminarem.• try {
uma_thread.join( ); // uma_thread.join(tempo). . . }
catch (InterruptedException e) { … }
Escalonamento de ThreadsPrioridade 10
Prioridade 1
Prioridade 9
Prioridade 8
Prioridade 2
Prioridade 3
.
.
.
A B
C
D E F
G
Exemplo 02
• Prioridades de Threads• Utilize o método setPriority(int) para
mudar a prioridade de threads– Utilize 01 thread com prioridade 1, 01 com
prioridade 09 e as outras com prioridade 5.– Faça com que uma das threads de alta
prioridade durma por 10 ms antes de terminar.
– Faça com que outra thread de alta prioridadefaça uma entrada de dado.
Exemplo 03
• Problema Produtor X Consumidor- Com buffer de tamanho 1.- Variáveis compartilhadas.- A solução do problema seria utilizar-se duas
THREADS: 01 consumidor e 01 produtor.- O que ocorre se não houver sincronização
entre a leitura e escrita?
UML do Exemplo 03
Thread
Produtor Consumidor
Principal
Bufferescrever ler
Exemplo 04
• Problema do Produtor X Consumidor com sincronização do Buffer.
• Em Java, a sincronização entre threads éfeita através do conceito de monitores.
• Monitor é um agrupamento de funções, cujas execuções não podem se dar de forma concorrente.
Exemplo 04
• Utilizar os métodos multuamenteexcludentes de um objeto como do tipo synchronized em Java.
• Utilizar os métodos wait( ) e notify( ) parabloquear e liberar, respectivamente, as threads.
• Escreva uma classe em Java chamadaSemaforo que implente as primitiva P(s) e V(s).
Exemplo 5
• Utilização da Classe Semarofo pararesolver o problema de Produtor-Consumidor:– Utilizar dois objetos (instâncias) da classe
Semaforo.• s1 e s2• Valores iniciais: s1 = 1; s2 = 0;
A interface Runnable
• Para utilizar multithreads em Java é necessárioinstanciar um objeto de uma classe que estendea classe básicaThread, certo?
• Uma vez que Java não possui herança múltipla, como eu posso utilizar um objeto, cuja classe jáé derivada, como no caso da ClasseThread? – public class Filho extends Pai extends Thread {……………….} // isto nao eh possivel em Java
A interface Runnable
• A solução encontrada em Java foi a utilização de uma interface: Runnable– No caso, tem-se de implementar esta
interface, que possui o método run( ).– public class Filho extends Pai implements Runnable– Ao implementar uma interface, a classe se capacita a
ser tratada como se fosse um objeto do tipo dainteface implementada.
• Se a classe Filho implementar a interface Runnable, elapode ser tratada como tal.
A interface Runnable
• Cria-se uma thread (Classe Thread), passando para o seu construtor umareferência do objeto que implementa a interface Runnable.– Thread uma_Thread = new Thread(Runnable obj_thread)– Thread uma_Thread = new Thread(Runnable obj_thread,
String nome_da_thread)
Solução Baseada na Interface Runnable
Thread
Classe BRunnable
referência
Classe A
Solução Baseada em Herança da Classe Thread
Thread
Classe B instanciação
Exemplo 6
• Classe para exemplificar a utilização da interface Runnable para implementação de Threads.