Conheça o Plugfeed | » Início » Desenvolvimento » Executando processos paralelos com a utilização de Threads
Conheça o Plugfeed | » Início » Desenvolvimento » Executando processos paralelos com a utilização de Threads -->
 
Avaliação: | Publicado em: 01/03/2007
Executando processos paralelos com a utilização de Threads
Dayvid Lima Desenvolvedor Java há mais de 5 anos, atualmente consultor java em empresa multinacional utilizando recursos avançados da tecnologia J2EE com servidores de aplicação em plataforma Solaris para gerenciamento de redes e integração de sistemas.
Executando processos paralelos com a utilização de Threads

Nesse artigo irei demonstrar como podemos executar mais de uma tarefa ao mesmo tempo utilizando Threads do Java, com esse recurso é possível iniciar mais de um processo ao mesmo tempo, controlar cada um dos processos a ponto de fazer com que o seu programa aguarde a finalização dos mesmos para continuar a execução ou fazer com que o seu programa continue a execução enquanto os processos ainda estão rodando.
 
Como sempre estarei colocando primeiro os códigos fonte dos arquivos. Para esse exemplo estaremos utilizando duas classes, uma que será a nossa "Thread" em si, e a outra será quem estará controlando/utilizando essa nossa Thread, através desse controlador iremos instanciar duas vezes a nossa Thread e as duas instancias estarão rodando ao mesmo tempo.
 
Para a nossa thread (MyThread) em si criei um exemplo bem simples, é apenas uma classe que estende o objeto Thread do java, nela temos um método chamado "run", que quando executado imprime uma mensagem X vezes na tela.
 
public class MyThread extends Thread {
    private String message;
    private int qtdRepeticoes = 500;

    public MyThread(String message) {
        this.message = message;
    }
    public void run() {
        for (int i = 0; i < this.qtdRepeticoes; i++) {
            System.out.print(message);
        }
        System.out.println("FIM da Thread: " + message + "!");
    }
}
 
Em nossa classe controladora, instanciamos duas vezes o objeto MyThread e em ambas as instancias chamamos o método "run" - em uma thread o método é "run" porém para chamá-lo utilizamos "start" e não "run".
 
public class CallMyThread {
 
    public static void main(String[] args) throws InterruptedException {

        MyThread t1 = new MyThread("a");
        MyThread t2 = new MyThread("b");

        t1.start();
        t2.start();

        //t1.join();
        //t2.join();

        System.out.println("Fim do Programa");

    }
}


Entendendo o código:

Agora vamos entender como funciona, primeiro nossa classe MyThread:

Aqui dizemos que nossa classe MyThread é uma subclasse da classe Thread, que é fornecida pelo pacote java.lang (por isso não precisamos fazer nenhum import).
    public class MyThread extends Thread {

O primeiro método da classe é o seu construtor, que recebe uma String e atribui o valor recebido a variável "message".
    public MyThread(String message) {
        this.message = message;
    }

O método seguinte é o método "run", esse é o método principal dessa classe pois é por aqui que damos início a execução da mesma.
    public void run() {
        for (int i = 0; i < this.qtdRepeticoes; i++) {
            System.out.print(message);
        }
        System.out.println("FIM da Thread: " + message + "!");
    }

No nosso caso quando esse método for chamado ele fará com que seja impresso na tela o valor da variável "message" a quantidade de vezes definida na variável "qtdRepeticoes" e assim que terminar escreverá "FIM da Thread: X !".

Nota: Eu deixei o número de repetições alto (500) pois caso contrário quando estiver rodando você não conseguirá ver a execução das duas Threads ao mesmo tempo.

Agora vamos ver a nossa classe CallMyThread, nessa classe temos apenas o método "main" que cria dois objetos do tipo "MyThread":
    MyThread t1 = new MyThread("a");
    MyThread t2 = new MyThread("b");

Para o primeiro objeto passamos como parâmetro a letra "a" e para o segundo passamos a letra "b".

Após instanciar os objetos t1 e t2, invocamos o método "run" deles:
    t1.start();
    t2.start();

Com isso estamos fazendo as duas threads rodarem, a primeira irá imprimir na tela 500 vezes a letra "a" e a segunda 500 vezes a letra "b".

Notem que para que a segunda thread "t2" rode, não é necessário que a primeira tenha terminado de executar, ou seja, o programa inicia a "t1", depois a "t2" e em seguida já mostra na tela "Fim do programa":
    System.out.println("Fim do programa");

Como as duas threads estarão rodando ao mesmo tempo, e cada uma delas imprimindo na tela valores diferentes - "a" e "b", você verá "a" e "b" misturados na tela.

Rode o programa algumas vezes e você terá resultados diferentes a cada vez, em algumas vezes a frase "Fim do programa" irá aparecer logo no início, outras vezes não e a seqüência de "a" e "b" será diferente.

Agora você deve estar se perguntando "para que as linhas comentadas?":
    //t1.join();
    //t2.join();

É bem simples, note que quando você rodou o seu programa na maioria (senão em todas) as vezes, você recebeu a mensagem "Fim do programa" logo no início, antes mesmo da seqüência de "a" e "b", isso acontece porque você esta falando para o seu programa:
    1 - criar duas threads
    2 - rodar essas duas threads
    3 - mostrar a mensagem "fim" na tela

Como estamos criando threads, o programa vai criar as threads como um processo separado e continuar a sua execução, como o processo de "mostrar a frase fim" é mais rápido do que fazer um "for" ele acaba mostrando antes das threads rodarem.

Porém existe uma forma de dizer ao programa "Ei, rode as threads ao mesmo tempo, mas espere até que elas terminem para avançar", isso é feito chamando o método "join" de cada thread.

Descomente as linhas:
    t1.join();
    t2.join();

E veja que agora a frase "Fim do programa" sairá sempre no final, depois que as duas threads já finalizaram.

Nota: A utilização do método "join" por causar uma "InterruptedException", por isso devemos realizar o tratamento dessa exception, o fazer um "throw" como fazemos aqui.
public static void main(String[] args) throws InterruptedException {

Esse é um pequeno exemplo de como criar e executar processos paralelos utilizando "threads", ainda existe muita coisa que não foi abordada aqui, mas espero que esse artigo tenha ajudado a ter uma visão melhor de como esse processo funciona.

Abraços e até o próximo,
Dayvid


Tenho uma dúvida. Não tem a ver com o artigo, mas espero que consiga me ajudar. É possível invocar uma página asp de um programa java? Ou utilizar o componente jmail em Java?
Obrigado.
Abner Luis <abner@inf.ufsc.br>
Tive que implementar threads uma vez, em um projeto disciplinar. Na época não tinha a menor idéia, era uma assunto que ainda não tinha visto. Penso que se eu tivesse esta visão de como uma thread funciona, teria sido beeeem mais fácil.
Gostei muito.
Artigo muito esclarecedor pra quem está começando a estudar threads e encontra algumas dificuldades pra entender o seu princípio de funcionamento. Mas acompanhando este artigo e o que fala sobre RMI surgiu uma dúvida: será possivel fazer uma integração entre processos multithreading utilizando RMI??

Parabéns pelo artigo.









Um produto Detetive.net