terça-feira, maio 08, 2007

Introdução a Threads - Programação paralela

Você sabe o que é uma Thread? Tem uma vaga idéia pelo menos (como eu tinha até alguns dias atrás)? Bom vou escrever aqui sobre esse bichinho místico que apavora todo mundo que pensa na prova de certificação Java :P .

Bom thread referisse ao processamento paralelo em Java... bá que grande ajuda a minha para você não é? Ta bom, vamos ver então mais didaticamente, diretamente do Java tutorial a Sun que diz mais ou menos isso:

Usuários de computadores têm a certeza de que seus sistemas podem fazer mais de uma coisa ao mesmo tempo. Eles assumem que eles podem continuar trabalhando em um editor de textos, enquanto outras aplicações descarregam arquivos, gerenciam a pilha de impressões, e reproduzem áudio. Desde uma simples aplicação é esperado que ela faça mais de uma coisa ao mesmo tempo. Por exemplo, uma aplicação que reproduz áudio deve simultaneamente ler o arquivo digital da rede, descompactá-lo, gerenciar a lista de músicas, e atualizar o visor. Até um editor de texto deve sempre ler e responder aos eventos de teclado e mouse, não importando o quanto ocupado ele já esteja reformatando textos ou atualizando o monitor. Um programa que pode fazer isso é conhecido como uma aplicação concorrente.

Sacou? Dae as THREADS meu filho! :)

Bueno, se tu for lá no Java Tutorial vai ver que eles falam em processos e threads... eu não pretendo escrever aqui, ou traduzir, sobre o que é isso - essa diferença - meu intuito é apenas mostrar como usar threads e algumas das opções que temos quando trabalhamos com elas (como sleep, join, etc...).

Bom entenda que você pode implementar uma thread de duas maneiras:

- Implementando a interface Runnable que declara o método run que contém o código da thread. Este objeto Runnable é passado por parâmetro para o contrutor do objeto Thread, como no exemplo abaixo:

public class ObjetoRunnable implements Runnable {

public void run() {
String passos[]=
new String[]{"Lendo arquivo properties...",
"Recuperando URL do SGBD...", "Recuperando usuário
e senha de acesso a base...", "Abrindo uma conexão...",
"Salvando dados...",};

for(int i = 0; i <>
System.out.println(passos[i]);
}
}

public static void main(String[] args) {
Thread t = new Thread(new ObjetoRunnable());
t.start();

System.out.println("... fazendo qualquer outra coisa...");
}
}

A saída impressa no console é:

... fazendo qualquer outra coisa...
Lendo arquivo properties...
Recuperando URL do SGBD...
Recuperando usuário e senha de acesso a base...
Abrindo uma conexão...
Salvando dados...

- Estendendo a classe Thread. A própria classe Thread implementa Runnable, Embora seu método run não faça nada. Uma aplicação pode estender Thread, provendo sua própria implementação de run, como no exemplo abaixo:

public class ObjetoThread extends Thread{
public void run() {
String passos[]=
new String[]{"Lendo arquivo properties...",
"Recuperando URL do SGBD...", "Recuperando usuário
e senha de acesso a base...", "Abrindo uma conexão...",
"Salvando dados...",};

for(int i = 0; i <>
System.out.println(passos[i]);
}
}

public static void main(String[] args) {
ObjetoThread objT = new ObjetoThread();
objT.start();

System.out.println("... fazendo qualquer outra coisa...");
}
}

A saída é a mesma que a do outro exemplo. Note que invocamos o método start() e deixamos ele rodando enquanto seguimos em frente. Prova "viva" do paralelismo do nosso programa :).

Bem é mais provável que você veja e use a primeira abordagem, pois ela é mais flexível que a segunda por não lhe forçar a estender uma classe, o que poderia lhe limitar em algum momento.

Bom nossos exemplos não são de grande serventia, mas pense em um programa que você precise desviar o fluxo dividindo uma atividade. Aqui nos exemplo as threads estão funcionando de forma assíncrona uma vez que a thread principal (main), que todo programa Java tem, não espera pelo resultado da outra thread mas você poderia delegar a uma thread uma tarefa que não está no escopo do seu programa, como preparar alguma coisa no sistema ou fazer uma validação qualquer, e aguardar o seu término para seguir em frente.

Bom, foi apenas um overview, quem quiser saber mais sobre o assunto deve ler o Java Tutorial e pesquisar mais a fundo sobre o assunto em livros e sites mas eu prometo que uma hora dessas eu posto um exemplo de thread síncrona :P.

3 comentários:

Carlos Heuberger disse...

Artigo bastante bom,
mas não entendi o que voce quis dizer no segundo caso (estendendo Thread) com "Note que invocamos o método run()". Não seria o start(), como realmente escrito no exemplo "objT.start()"?

Alias, até seria um erro ativar o Thread atraves do run, tipo: "objT.run()". Nesse caso o código é executado normalmente, sem rodar num Thread, sem paralelismo.

Abraços.

Jean Michel disse...

Realmente estava dormindo quando escrevi isso... é start() mesmo!!!

Vou arrumar assim que puder o post :D

Obrigado, e vlw pela visita e comment.

Jean

Anônimo disse...
Este comentário foi removido por um administrador do blog.