Canais iMasters

Java + Desenvolvimento

How-To: Implementando Threads em Java

Este é um tópico que costuma ser evitado por muitos e adorado por poucos. Estamos falando de Threads em Java. Uma vez que se aprende o princípio básico, sempre veremos necessidades de utilização, seja para concorrência ou até mesmo para coisas mais simples, como mostrar uma barra de progresso.

Uma Thread é similar à um programa com início, sequência de execução e fim em qualquer momento de sua execução. Porém a Thread não é um programa, já que não pode ser executada sozinha. Ela deve ser executada dentro de uma aplicação, e esta aplicação possuirá vários pontos de execuções, cada um representando uma Thread.

Tema também muito comum em entrevistas são os questionamentos sobre as Threads.

Como implementar, por exemplo?


Existem duas formas para isso:

01. Estendendo a Classe java.lang.Thread;
02. Implementando a Interface java.lang.Runnable.

Mas aí você pergunta: “já que é tão bom e sempre vou querer usar, quando precisarei usar?”


Nós usamos thread se queremos que uma parte de nosso código seja executado em paralelo. Para isso, devemos colocar o código dentro do método run(), da classe Thread ou da Interface Runnable.

Na verdade, o método run() pertence à Interface Runnable, e como a Classe Thread implementa essa Interface, ela também possui esse método.

Outra pergunta comum: “Qual a melhor maneira de implementar uma Thread? Estendendo a Classe Thread ou Implementando a Interface Runnable?”

A resposta acaba sendo uma questão de conhecimento da Orientação a Objetos, e não de conhecer Thread. Lembram de um dos princípios da OO, que diz que devemos ter cuidado com Herança, pois ela nos limita? E também como no Java não temos Herança múltipla (esqueçam a simulação através de interfaces), se herdarmos a Classe Thread estamos gastando nossa chance e não poderemos herdar outra caso precisarmos.

E não acredito que seja uma verdade absoluta, então gostaria de ouvir contra-argumentações sobre isso nos comentários.

Outra razão para a utilização da Interface é que, de acordo com OO, só devemos estender uma classe quando iremos prover novas funcionalidades para esta. Como na maioria dos casos só queremos usar o método run(), não tem por que estendermos.

Uma thread não será executada até que o método start() seja chamado.

Quando chamamos o método start(), a JVM executa o método run() a partir de uma thread própria, diferente da que está chamando o processo.

Se tentarmos chamar uma thread diretamente pelo método run(), ela será executada na mesma thread que está chamando, e não na sua própria thread, não havendo concorrência alguma e não fazendo sentido sua utilização.

Já se chamarmos o método start() duas vezes seguidas no mesmo Objeto Thread, ocorrerá uma exceção:

thread.start();
thread.start();// Essa linha irá gerar uma IllegalThreadStateException

Vamos agora ao nosso exemplo prático, no qual faremos das duas formas já apresentadas:

//Extendendo a classe Thread
class TesteThread extends Thread{

public void run(){
System.out.println("Estou sendo executado pela Thread de nome: " + Thread.currentThread().getName());
}
}

//Implementando a Interface Runnable
class TesteRunnable implements Runnable{

public void run(){
System.out.println("Estou sendo executado pela Thread de nome: " + Thread.currentThread().getName());
}
}

//iniciando a Thread
Thread testeThread = new TesteThread();
testeThread.setName("T1");
Thread testeRunnable = new Thread(new TesteRunnable(),"T2");

testeThread.start();
testeRunnable.start();

Uma thread estará no estado “finalizada” quando a execução do método run() terminar e você não puder chamar o método start() novamente.

Caso tenham gostado, deixem nos comentários e providenciaremos mais!

Referências:
http://www.xyzws.com/Javafaq/can-the-run-method-be-called-directly-to-start-a-thread/13
http://javarevisited.blogspot.com/2011/02/how-to-implement-thread-in-java.html


Comente também

8 Comentários

André Gontijo
André Gontijo

Não seria testeRunnable.run() ?
e gostaria de saber sobre como dividir um FOR para várias threads executarem.

Claudio Roberto França Pereira
Claudio Roberto França Pereira

Na verdade o que é iniciado é sempre uma Thread. O lance de implementar a interface Runnable é só pra casos específicos que você já esteja herdando de outra classe, e mesmo assim, você usa um Thread pra rodar o seu objeto Runnable. Pode ver que o construtor da Thread recebe o Runnable pra saber o que fazer quando ela for iniciada.

Sobre a divisão do FOR, pra dividi-lo em 4 threads, por exemplo, você vai ter que criar 4 classes só praquele FOR. Java não tem a funcionalidade de paralelizar loops, o uso de threads é mais voltada para interfaces e I/O.

Paulo Chaves
Paulo Chaves

Bom o tutorial....mas tô iniciando tô com um pouco de dificuldade em entender Threads..Tô criando o jogo d velha e tenho que disponibilizá-la via socket (usando servidor/cliente) e o erra tá exatamente na Thread...
Parabéns amigo.

Extreme Java
Extreme Java

I also posted about how to create threads in Java at <a href="http://extreme-java.com/introduction-to-multi-threading/">Introduction to Multi-Threading</a>

Andrey Knupp Vital
Andrey Knupp Vital

Boa ! só faltou falar sobre o synchronized ..

Rodrigo
Rodrigo

Muito bom, so que o framework Quartz utiliza esse conceito de threads? Parabéns pelo post.

Anderson Melo
Anderson Melo

Gostei do artigo. Simples, direto e interessante.

Qual a sua opinião?

Comentários considerados ofensivos serão moderados.
IBM

Parceiros

IBM
PagSeguro
Internet Innovation
Dialhost
HostNet
Tecla
KingHost
DotStore
Dinamize