"Ciao, Amigo! Ellie ti ha parlato dei thread e io ti dirò come ci lavori. Per creare un nuovo thread, devi:"

1)  Create un oggetto Thread

2) Passa il metodo che vuoi eseguire

3)  Chiamare il metodo start sull'oggetto Thread creato.

Considera questo esempio:

Codice Descrizione
class Printer implements Runnable
{
public void run()
{
System.out.println("I’m printer");
}
}
Classe che implementa l' interfaccia Runnable .
public static void main(String[] args)
{
Printer printer = new Printer();
Thread childThread = new Thread(printer);
childThread.start();
}
1 Creare un'istanza della classe Printer, che implementa il metodo run.
2 Creare un nuovo oggetto Thread. Passiamo al costruttore l'oggetto stampante, il cui metodo run() deve essere invocato.
3 Avviare il nuovo thread chiamando il metodo start() .

I piccoli programmi Java di solito sono costituiti da un thread chiamato «thread principale». Ma i programmi lanciano più spesso thread aggiuntivi, chiamati "thread figlio". Il thread principale esegue il metodo principale e termina. Il metodo run di Runnable è il metodo analogo per i thread figlio.

"Ah, molti thread significano molti metodi principali."

Creazione e avvio di nuovi thread - 1

Per dire a un oggetto Thread quale metodo specifico dovrebbe iniziare, dobbiamo in qualche modo passargli un metodo. In Java, questo viene fatto utilizzando l' interfaccia Runnable . Questa interfaccia contiene un singolo metodo astratto: void run() . La classe Thread ha un costruttore Thread(Runnable Runnable) . Puoi passare qualsiasi oggetto che implementa l' interfaccia Runnable .

La tua classe deve ereditare Runnable e sovrascrivere il suo metodo run . Invocare questo metodo è ciò che avvia il nuovo thread. Puoi scrivere quello che vuoi nel metodo run .

Codice Descrizione
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 che implementa l'interfaccia 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();
}
Crea due thread, ognuno dei quali sarà basato sul proprio oggetto 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();
}
Crea tre thread basati su un singolo oggetto Printer.

Inoltre, puoi combinare tutto questo in un'unica classe. La classe Thread eredita l'interfaccia Runnable , quindi devi solo eseguire l'override del suo metodo run:

Un altro modo per creare un nuovo thread
class Printer extends Thread
{
private String name;
public Printer(String name)
{
this.name = name;
}
public void run()
{
System.out.println("I’m " + this.name);
}
}
Eredita la classe Thread , che implementa l' interfaccia Runnable , quindi esegue l'override del metodo run .
public static void main(String[] args)
{
Printer printer = new Printer("Jack");
printer.start();

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

}
Crea due thread, ognuno dei quali sarà basato sul proprio oggetto Printer .

"Questa è una soluzione più elegante."

"Sì, ma ha i suoi difetti:"

1)  Potrebbe essere necessario avviare più thread basati su un singolo oggetto, come nell'esempio con Natasha.

2)  Se erediti dalla classe Thread, non puoi aggiungere un'altra classe genitore alla tua classe.

3)  Se la tua classe ha una classe genitore, non puoi aggiungere Thread come seconda classe genitore.

"In altre parole, dopo che il metodo start è stato chiamato, ciascuno dei thread avvia l'esecuzione del metodo run dell'oggetto passato al costruttore?"

"Sì. Se non viene passato nulla al costruttore, allora Thread esegue solo il suo metodo run interno."

"Ma perché non chiamiamo semplicemente il metodo in questo modo?"

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

"Quando il thread principale raggiunge il metodo run , il suo " robottino " entra semplicemente ed esegue tutti i comandi al suo interno. Solo dopo che sono stati eseguiti tornerà al metodo principale e continuerà a eseguire ulteriori comandi. Quindi, nessun secondo " piccolo robot" . Tutto il lavoro verrà eseguito in sequenza, non in parallelo (simultaneamente)."

"Capisco. Puoi chiamare qualche altro metodo, qualcosa di diverso dalla corsa?"

"No. È tutto legato all'interfaccia Runnable, che "conosce" solo uno dei suoi metodi: run() ."