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.
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!" );
}
}
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!" );
}
}
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();
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!
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