– Cześć, Amigo! Oto ciekawe zagadnienie, z którym albo już się zetknąłeś, albo nastąpi to lada chwila. Jak zatrzymać wykonywany wątek?

Powiedzmy, że użytkownik chce, aby program pobrał plik z internetu. Wątek główny tworzy osobny wątek podrzędny dla tego zadania i przekazuje mu obiekt, którego metoda run zawiera wszystkie niezbędne działania potrzebne do pobrania pliku.

Ale nagle użytkownik zmienia zdanie. Nie chce już ściągać pliku. Jak możemy anulować pracę i zatrzymać wątek?

– No jak?

Nie możemy. To najbardziej typowa i najpoprawniejsza odpowiedź. Nie można zatrzymać wątku. Tylko on sam może się zatrzymać.

Jednak możesz przekazać wątkowi informację, niejako sygnalizując, że praca nie musi już być wykonywana i że powinien się zakończyć. Tak jak wątek główny zostaje zakończony przez powrót z metody main, tak samo wątek podrzędny zostaje zakończony przez powrót z metody run.

– W jaki sposób najlepiej to zrobić?

– Możesz dodać jakąś zmienną, np. boolean. Jeśli jest true, wątek uruchamia się. Jeśli jest false , wątek powinien zostać zakończony. Jak na przykład tutaj:

Kod Opis
class Clock implements Runnable
{
public void run()
{
while (true)
{
Thread.sleep(1000);
System.out.println("Tik");

if (!ClockManager.isClockRun)
return;
}
}
}

Klasa Clock bez przerwy, co sekundę zapisuje słowo "Tik" do konsoli.

Jeśli ClockManager.isClockRun jest false, metoda run zostaje zakończona.

class ClockManager
{
public static boolean isClockRun = true;
public static void main(String[] args)
{
Clock clock = new Clock();
Thread clockThread = new Thread(clock);
clockThread.start();

Thread.sleep(10000);
isClockRun = false;
}

}
Wątek główny uruchamia wątek podrzędny (clock), który powinien działać nieprzerwanie

Odczekaj 10 sekund i przekaż wątkowi clock, że ma zakończyć działanie.

Wątek główny kończy swoją pracę.

Wątek clock kończy swoją pracę.

– A co jeśli mamy kilka wątków?

– Najlepiej jest mieć taką zmienną dla każdego wątku. Najwygodniej jest dodać ją bezpośrednio do klasy. Możesz dodać tam zmienną boolean isRun. Jednak lepszym rozwiązaniem jest dodanie zmiennej boolean isCancel, która zmieni się na true, gdy zadanie zostanie anulowane.

Kod Opis
class Clock implements Runnable
{
private boolean isCancel = false;

public void cancel()
{
this.isCancel = true;
}

public void run()
{
while (!isCancel)
{
Thread.sleep(1000);
System.out.println("Tik");
}
}
}
Klasa Clock co sekundę zapisuje słowo "Tik" do konsoli, tak długo jak isCancel jest false.

Kiedy isCancel staje się true, metoda run kończy działanie.

public static void main(String[] args)
{
Clock clock = new Clock();
Thread clockThread = new Thread(clock);
clockThread.start();

Thread.sleep(10000);
clock.cancel();
}
Wątek główny uruchamia wątek podrzędny (clock), który powinien działać nieprzerwanie

Odczekaj 10 sekund i anuluj zadanie, wywołując metodę cancel.

Wątek główny kończy swoją pracę.

Wątek clock kończy swoją pracę.

– Będę o tym pamiętać. Dzięki, Baśka.