– Cześć, Amigo! Basia opowiedziała ci o wątkach, a ja powiem Ci, jak z nimi pracować. Aby stworzyć nowy wątek, musisz:

1) Stworzyć obiekt Thread

2) Przekazać mu metodę, którą chcesz uruchomić

3) Wywołać metodę start na utworzonym obiekcie Thread.

Przeanalizuj ten przykład:

Kod Opis
class Printer implements Runnable
{
public void run()
{
System.out.println("Jestem drukarką");
}
}
Klasa, która implementuje interfejs Runnable.
public static void main(String[] args)
{
Printer printer = new Printer();
Thread childThread = new Thread(printer);
childThread.start();
}
1. Utwórz instancję klasy Printer, która implementuje metodę run.
2. Utwórz nowy obiekt Thread. Przekazujemy konstruktorowi obiekt printer, którego metoda run() musi zostać wywołana.
3. Uruchom nowy wątek, wywołując metodę start().

Krótkie programy w Javie składają się zazwyczaj z jednego wątku zwanego «wątkiem głównym». Ale programy częściej uruchamiają dodatkowe wątki, które są nazywane «wątkami podrzędnymi». Wątek główny uruchamia metodę main i kończy działanie. Metoda run interfejsu Runnable jest analogiczną metodą dla wątków podrzędnych.

– Aha, wiele wątków oznacza wiele metod main.

Tworzenie i uruchamianie nowych wątków - 1

Aby przekazać obiektowi Thread, którą konkretnie metodę powinien uruchomić, musimy daną metodę jakoś mu przekazać. W Javie odbywa się to za pomocą interfejsu Runnable. Ten interfejs zawiera jedną abstrakcyjną metodę: void run(). Klasa Thread posiada konstruktor Thread(Runnable Runnable). Możesz przekazać dowolny obiekt, który implementuje interfejs Runnable.

Twoja klasa musi dziedziczyć Runnable i nadpisywać jego metodę run. Wywołanie tej metody powoduje uruchomienie nowego wątku. Możesz napisać cokolwiek chcesz w metodzie run.

Kod Opis
class Printer implements Runnable
{
private String name;
public Printer(String name)
{
this.name = name;
}
public void run()
{
System.out.println("Jestem " + this.name);
}
}
Klasa, która implementuje interfejs 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();
}
Utwórz dwa wątki, z których każdy będzie oparty na własnym obiekcie Printer.
public static void main(String[] args)
{
Printer printer = new Printer("Natasza");

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

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

Thread thread3 = new Thread(printer);
thread3.start();
}
Utwórz trzy wątki na podstawie jednego obiektu Printer.

Co więcej, możesz połączyć to wszystko w jedną klasę. Klasa Thread dziedziczy interfejs Runnable , więc musisz tylko nadpisać jej metodę run:

Inny sposób tworzenia nowego wątku to:
class Printer extends Thread
{
private String name;
public Printer(String name)
{
this.name = name;
}
public void run()
{
System.out.println("Jestem " + this.name);
}
}
Dziedziczyć klasę Thread, która implementuje interfejs Runnable, a następnie nadpisać metodę run.
public static void main(String[] args)
{
Printer printer = new Printer("Jack");
printer.start();

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

}
Utwórz dwa wątki, z których każdy będzie oparty na własnym obiekcie Printer.

– To jest bardziej eleganckie rozwiązanie.

– Tak, ale ma swoje wady:

1) Może być konieczne uruchomienie kilku wątków na jednym obiekcie, jak w przykładzie z Nataszą.

2) Jeżeli dziedziczysz klasę Thread, nie możesz dodać innej klasy macierzystej do swojej klasy.

3) Jeżeli Twoja klasa ma klasę macierzystą, nie możesz dodać Thread jako drugiej klasy macierzystej.

– Innymi słowy, po wywołaniu metody start, każdy z wątków zaczyna wykonywać metodę run obiektu przekazanego do konstruktora?

– Tak. Jeżeli nic nie zostanie przekazane do konstruktora, wówczas Thread po prostu wykonuje swoją wewnętrzną metodę run.

– Ale dlaczego nie wywołamy metody tak po prostu?

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

– Kiedy wątek główny dotrze do metody run, jego „mały robocik” po prostu wchodzi do środka i wykonuje wszystkie komendy, które tam się znajdują. Dopiero po ich wykonaniu powróci do metody main i będzie kontynuował wykonywanie kolejnych poleceń. W ten sposób nie zostanie stworzony żaden drugi „mały robocik”. Cała praca będzie wykonywana sekwencyjnie, a nie równolegle (jednocześnie).

– Rozumiem. Czy możesz wywołać jakąś inną niż metoda run metodę?

– Nie. To wszystko jest związane z interfejsem Runnable, który tylko „wie” o jednej z jego metod: run().