"Olá, amigo! Ellie falou sobre threads e vou lhe contar como você trabalha com eles. Para criar um novo thread, você precisa:"

1)  Crie um objeto Thread

2) Passe o método que deseja executar

3)  Chame o método start no objeto Thread criado.

Considere este exemplo:

Código Descrição
class Printer implements Runnable
{
public void run()
{
System.out.println("I’m printer");
}
}
Classe que implementa a interface Runnable .
public static void main(String[] args)
{
Printer printer = new Printer();
Thread childThread = new Thread(printer);
childThread.start();
}
1 Crie uma instância da classe Printer, que implementa o método run.
2 Crie um novo objeto Thread. Passamos ao construtor o objeto impressora, cujo método run() precisa ser invocado.
3 Inicie o novo thread chamando o método start() .

Pequenos programas Java geralmente consistem em um thread chamado «thread principal». Mas os programas geralmente lançam threads adicionais, que são chamados de "threads filhos". O thread principal executa o método principal e termina. O método run do Runnable é o método análogo para threads filhos.

"Ah, muitos threads significam muitos métodos principais."

Criando e iniciando novos tópicos - 1

Para dizer a um objeto Thread qual método específico ele deve iniciar, precisamos de alguma forma passar um método para ele. Em Java, isso é feito usando a interface Runnable . Essa interface contém um único método abstrato: void run() . A classe Thread tem um construtor Thread(Runnable Runnable) . Você pode passar qualquer objeto que implemente a interface Runnable .

Sua classe deve herdar Runnable e substituir seu método run . Chamar esse método é o que inicia o novo thread. Você pode escrever o que quiser no método run .

Código Descrição
class Printer implements Runnable
{
private String name;
public Printer(String name)
{
this.name = name;
}
public void run()
{
System.out.println("I’m " + this.name);
}
}
Classe que implementa a interface Runnable.
public static void main(String[] args)
{
Printer printer1 = new Printer("Nick");
Thread thread1 = new Thread(printer1);
thread1.start();

Printer printer2 = new Printer("Jack");
Thread thread2 = new Thread(printer2);
thread2.start();
}
Crie dois threads, cada um dos quais será baseado em seu próprio objeto Printer.
public static void main(String[] args)
{
Printer printer = new Printer("Natasha");

Thread thread1 = new Thread(printer);
thread1.start();

Thread thread2 = new Thread(printer);
thread2.start();

Thread thread3 = new Thread(printer);
thread3.start();
}
Crie três threads com base em um único objeto Printer.

Além do mais, você pode combinar tudo isso em uma aula. A classe Thread herda a interface Runnable , então você só precisa sobrescrever seu método run:

Outra forma de criar um novo tópico
class Printer extends Thread
{
private String name;
public Printer(String name)
{
this.name = name;
}
public void run()
{
System.out.println("I’m " + this.name);
}
}
Herde a classe Thread , que implementa a interface Runnable e substitua o método run .
public static void main(String[] args)
{
Printer printer = new Printer("Jack");
printer.start();

Printer printer2 = new Printer("Jack");
printer2.start();

}
Crie dois threads, cada um dos quais será baseado em seu próprio objeto Printer .

"Esta é uma solução mais elegante."

"Sim, mas tem suas deficiências:"

1)  Pode ser necessário iniciar várias threads com base em um único objeto, como no exemplo com Natasha.

2)  Se você herdar da classe Thread, não poderá adicionar outra classe pai à sua classe.

3)  Se sua classe tiver uma classe pai, você não poderá adicionar Thread como uma segunda classe pai.

"Em outras palavras, depois que o método start é chamado, cada um dos threads começa a executar o método run do objeto passado para o construtor?"

"Sim. Se nada for passado para o construtor, Thread apenas executará seu método de execução interno."

"Mas por que simplesmente não chamamos o método assim?"

Código
public static void main(String[] args)
{
 Printer printer1 = new Printer("Nick");
 printer1.run();
}

"Quando a thread principal chega ao método run , seu "robôzinho" simplesmente entra e executa todos os comandos dentro dela. Só depois de executados é que ela volta para o método principal e continua a executar outros comandos. Assim, sem segundo " pequeno robô" será criado. Todo o trabalho será executado sequencialmente, não em paralelo (simultaneamente)."

"Entendo. Você pode chamar algum outro método, algo diferente de executar?"

"Não. Está tudo ligado à interface Runnable, que apenas "sabe" sobre um de seus métodos: run() ."