Vamos observar algumas outras diferenças entre Thread e Runnable com a ajuda do gráfico de comparação mostrado abaixo:
Gráfico de comparação
Base para Comparação | Fio | Runnable |
---|---|---|
Basic | Cada thread cria um objeto exclusivo e é associado a ele. | Vários segmentos compartilham os mesmos objetos. |
Memória | Como cada thread cria um objeto único, mais memória é necessária. | Como vários segmentos compartilham o mesmo objeto, menos memória é usada. |
Estendendo | Em Java, herança múltipla não é permitida, portanto, depois que uma classe extende a classe Thread, ela não pode estender nenhuma outra classe. | Se uma classe define thread implementando a interface Runnable, tem a chance de estender uma classe. |
Usar | Um usuário deve estender a classe de encadeamento somente se desejar substituir os outros métodos na classe Thread. | Se você deseja apenas se especializar em executar o método, a execução do Runnable é a melhor opção. |
Acoplamento | A extensão da classe Thread introduz um acoplamento rígido, pois a classe contém o código da classe Thread e também a tarefa atribuída ao thread | A implementação da interface Runnable apresenta um acoplamento flexível, pois o código do Thread é separado do trabalho dos Threads. |
Definição de Classe de Thread
Thread é uma classe no pacote java.lang . A classe Thread estende uma classe Object e implementa interfaces Runnable . A classe Thread possui construtores e métodos para criar e operar no encadeamento. Quando criamos vários segmentos, cada segmento cria um objeto exclusivo e é associado a esse objeto. Se você criar um segmento que estenda a classe Thread, mais você não poderá estender nenhuma outra classe, pois o java não suporta múltiplas heranças. Portanto, você deve optar por estender a classe Thread somente quando desejar também substituir alguns outros métodos da classe Thread. Vamos ver um exemplo de criação de um encadeamento que estende uma classe Thread.
/ * Definir um segmento * / Classe Mythread extends Thread {/ * job do segmento * / public void run () {para (int i = 0; i <10; i ++) {System.Out.Println ("Thread de Criança" ); }} Classe mainThread {/ * job do thread principal * / public static void main (args de seqüência []) {Mythread mt = new Mythread (); / * thread principal criou o thread filho * / mt.start (); para (int i = 0; i <10; i ++) {System.Out.Print ("Thread principal"); }}} / * Saída * / Main Thread Main Thread Principal Thread Main Thread Principal Thread Child Thread Principal Thread Principal Thread Principal Thread Principal Thread Principal Thread Principal Thread Principal
No código acima, eu crio uma classe Mythread que estende a classe Thread e sobrescreve um método de execução da classe Thread. Na classe que contém o método main eu crio um objeto de thread (mt) da classe Mythread e usando o objeto thread invocado o método start (). O método start inicia a execução do encadeamento e, ao mesmo tempo, a JVM chama o método de execução do encadeamento. Agora, há dois encadeamentos no encadeamento principal de um programa e no segundo encadeamento filho criado pelo encadeamento principal. A execução de ambos os encadeamentos ocorre simultaneamente, mas a saída exata não pode ser fingida.
Definição de Interface Runnable
Runnable é uma interface no pacote java.lang . Implementando a interface Runnable podemos definir um thread. A interface executável tem um único método run (), que é implementado pela classe que implementa a interface Runnable. Quando você escolhe definir um thread implementando uma interface Runnable, ainda tem a opção de estender qualquer outra classe. Quando você cria vários segmentos implementando a interface Runnable, cada thread compartilha a mesma instância executável. Vamos aprender como definir um thread usando a interface Runnable.
/ * Definir um thread * / Classe Runnablethread implementa Runnable {/ * job do thread * / public void run () {para (int i = 0; i <10; i ++) {System.Out.Println ("Thread de Criança" ); }} Classe mainThread {/ * job do thread principal * / public static void main (args de seqüência []) {Mythread rt = new Mythread (); / * thread principal criou o objeto runnable * / Thread t = new Thread (rt); / * thread principal cria um thread filho e passou o objeto executável * / t.start (); para (int i = 0; i <10; i ++) {System.Out.Print ("Thread principal"); }}} / * Saída * / Main Thread Main Thread Principal Thread Main Thread Principal Thread Child Thread Principal Thread Principal Thread Principal Thread Principal Thread Principal Thread Principal Thread Principal
No código acima, eu criei uma classe Runnablethread que implementa a interface Runnable e define o trabalho do thread implementando o método run () da interface Runnable. Então eu crio uma classe mainthread contendo o método main. Dentro do método main, eu declarei um objeto executável da classe Runnablethread e passei este objeto para o construtor Thread enquanto declarava um thread. Desta forma, eu liguei o objeto thread (t) com um objeto executável (rt). Em seguida, o objeto thread invoca o método start do thread que invoca ainda o método run da classe Runnablethread. Se eu não tivesse vinculado o objeto executável ao objeto Thread, então o método start de threads teria chamado o método run da classe Thread. Agora, novamente, existem dois encadeamentos no código, o encadeamento principal e o encadeamento principal criam o encadeamento filho ambos executados simultaneamente, mas a saída exata nunca pode ser fingida.
Principais diferenças entre thread e executáveis em Java
- Cada encadeamento criado pela extensão da classe Thread cria um objeto exclusivo para ele e é associado a esse objeto. Por outro lado, cada thread criado pela implementação de uma interface Runnable compartilha a mesma instância executável.
- Como cada encadeamento é associado a um objeto único quando criado pela extensão da classe Thread, é necessária mais memória. Por outro lado, cada thread criada pela implementação da interface Runnable compartilha o mesmo espaço de objeto, portanto, requer menos memória.
- Se você estender a classe Thread, então, você pode herdar qualquer outra classe, pois Java não permite herança múltipla, enquanto implementar Runnable ainda fornece uma chance para uma classe herdar qualquer outra classe.
- É preciso estender uma classe Thread somente se ela tiver que substituir ou especializar alguns outros métodos da classe Thread. Você deve implementar uma interface Runnable se desejar apenas especializar o método de execução.
- A extensão da classe Thread introduz um acoplamento rígido no código, pois o código de Thread e o job do thread estão contidos na mesma classe. Por outro lado, a interface Implementing Runnable introduz o acoplamento flexível no código, pois o código do Thread é separado da tarefa atribuída ao thread.
Conclusão:
É preferível implementar uma interface Runnable em vez de estender a classe Thread. Como implementar o Runnable, seu código é fracamente acoplado, já que o código do thread é diferente da classe que atribui o job ao thread. Requer menos memória e também permite que uma classe herde qualquer outra classe.