terça-feira, 14 de agosto de 2012

Trabalhando com Thread e Runnable em Java


Muito conteúdo para a certificação SCJP está relacionado às Threads. Discutiremos aqui alguns detalhes interessantes associados ao funcionamento desses recursos no Java.

O que é uma Thread?
Isso deve estar claro para você! Certamente já teve oportunidade de trabalhar com Threads em outras linguagens de programação como C ou Delphi. Ou até mesmo em Java. Threads são processos que rodam concorrentemente. Podemos executar processos concorrentes no Java de duas formas: herdando a classe Thread ou implementando a interface Runnable.
 
Qual é a diferença?
Pensando no mundo OO, quando criamos uma classe que herda as características de Thread, entendemos que a subclasse seria uma especialização da Thread. Isso significa que outros objetos utilizariam a thread filha como um objeto Thread com comportamentos e atributos especiais. Se precisarmos de comportamento concorrente em determinado código da aplicação, não significa que esses objetos seriam especializações de Thread, e sim que são objetos com abstrações particulares que, por certo motivo, precisam operar simultaneamente. Neste caso, os objetos implementariam a interface Runnable - não seriam especializações de Threads.
 
Ainda não entendi!
Seguinte: quando você resolver criar uma nova categoria de Thread, estende-a em seja feliz! Se você quiser que sua aplicação rode processos paralelos, implemente a interface Runnable em suas classes! Só isso! É uma boa prática trabalhar dessa forma.
 
Vamos agora aos exemplos. O código abaixo herda o objeto Thread:
 
package org;

public class MyThread extends Thread {

    public MyThread() {}
    
    public MyThread(Runnable runnable) {
        super( runnable );
    }
    
    public void run() {
        System.out.println( "Eu sou uma thread!" );
    }
    
}
 
Observe alguns detalhes: Os dois constructors foram colocados para comportar os próximos exemplos deste artigo. Caso você opte em utilizar esse panorama (pow, não sei porque, mas lembrei agora da música panama do Van Halen e resolvi escutá-la - veja no link http://www.youtube.com/watch?v=QDJg-WjjSYI)...
...
Qual era o papo mesmo?! A sim! Se você optar em construir objetos neste panorama, você pode (é opcional) especifica o código concorrente dentro do método run(). Você poderá executar essa thread da seguinte forma:
 
new MyThread().start();
 
Vamos ao segundo exemplo:
 
package org;

public class MyRunnable implements Runnable {

    @Override
    public void run() {
        System.out.println( "Eu sou uma classe que implementa Runnable!" );
    }
  
}
 
Neste caso, uma classe qualquer é criada e implementa Runnable. Ao implementar essa interface, obrigatoriamente você precisa especificar o método run(). Neste caso, a chamada da thread seria:
 
Thread thread = new Thread( new MyRunnable() );
thread.start(); 

Observe que passamos o nosso objeto MyRunnable como parâmetro de uma Thread comum e depois chamamos start(). O método sobrescrito na classe MyRunnable será chamado.
 
Muita atenção agora!
Agora uma questão interessante (que inclusive cai na prova SCJP): Se iniciarmos uma Thread MyThread passando como parâmetro o objeto MyRunnable? Qual método run() será chamado, o da MyThread ou o da MyRunnable? Execute o código abaixo e descubra:

package org;

public class Test3 {

    public static void main(String[] args) {
        
        new MyThread().start();
        
        Thread thread = new Thread( new MyRunnable() );
        thread.start();
        
        MyThread myThread = new MyThread( new MyRunnable() );
        myThread.start();

    }

}
 
É isso mesmo! Ao sobrescrever o método run() em uma subclasse de Thread, ele é utilizado em qualquer situação, mesmo que você entre com uma implementação de Runnable na construção da classe. Isso significa que sua saída foi:
 
Eu sou uma thread!
Eu sou uma classe que implementa Runnable!
Eu sou uma thread!
 
Existe muitos outros assuntos relacionados a Threads que devem ser explorados, porém deixarei para artigos futuros.
 
Espero ter ajudado!
Guilherme Pontes

Nenhum comentário:

Postar um comentário