– Cześć, Amigo! Musisz przyznać, że pomysł Basi dotyczący Cancel był genialny.

– Tak.

– Tak naprawdę, coś podobnego istnieje w klasie Thread. Tylko zmienna nie nazywa się isCancel. Nazywa się isInterrupt. A metoda używana do zatrzymania wątku to nie cancel(). To interrupt().

– Naprawdę?

– Tak. Sprawdź, jak to działa.

Kod Opis
class Clock implements Runnable
{
public void run()
{
Thread current = Thread.currentThread();

while (!current.isInterrupted())
{
Thread.sleep(1000);
System.out.println("Tik");
}
}
}
Ponieważ wiele wątków może wywoływać metodę run na tym samym obiekcie Clock, otrzymujemy obiekt Thread dla bieżącego wątku.

Klasa Clock wpisuje słowo "Tik" do konsoli raz na sekundę tak długo, jak zmienna isInterrupt bieżącego wątku przyjmuje wartość false.

Gdy isInterrupt 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);
clockThread.interrupt();
}
Wątek główny uruchamia wątek podrzędny (clock), który powinien działać bez końca.

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

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

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

Co więcej, metoda sleep, której ludzie tak bardzo lubią używać w niekończących się pętlach w metodzie run, automatycznie sprawdza zmienną isInterrupt. Jeśli wątek wywołuje metodę sleep, metoda ta najpierw sprawdza, czy isInterrupt przyjmuje wartość prawda dla tego wątku. Jeśli jest true, wątek nie „zaśnie”. Zamiast tego wyrzuci wyjątek InterruptedException.

– Dlaczego wyrzuci wyjątek? Czy nie lepiej byłoby po prostu umieścić w pętli isInterrupted() zamiast isCancel()?

Po pierwsze, metoda run nie zawsze ma pętlę. Metoda ta może po prostu składać się z kilkudziesięciu wywołań do innych metod. Wówczas musiałbyś dodać sprawdzenie isInterrupted przed każdym wywołaniem metody.

Po drugie, niektóre metody, które wykonują wiele różnych operacji, mogą potrzebować bardzo dużo czasu.

Po trzecie, wyrzucenie wyjątku nie zastępuje sprawdzenia isInterrupted. Jest to po prostu wygodny dodatek. Wyrzucony wyjątek pozwala na szybkie odwinięcie stosu wywołań z powrotem do samej metody run.

Po czwarte, metoda sleep jest używana bardzo często. Jak się okazuje, ta pomocna metoda jest wzbogacona o ukrytą kontrolę, która jest nie mniej pomocna. To tak, jakby nikt specjalnie nie dodał tej kontroli, ale mimo wszystko ona jest. Jest to bardzo przydatne, gdy używasz cudzego kodu i nie możesz sam dodać sprawdzenia.

Po piąte, dodatkowa kontrola nie pogarsza wydajności. Wywołanie metody sleep oznacza, że wątek nie powinien robić nic (poza spaniem), więc dodatkowa praca nikomu nie przeszkadza.

– To są poważne argumenty.

– I, na koniec, jeszcze to: Twoja metoda run może wywołać czyjś kod - kod, do którego nie masz dostępu (kod źródłowy i/lub prawa do zmiany kodu). Może nie mieć kontroli isInterrupted i może używać „try ... catch (Exception e)”, aby wyłapać wszystkie wyjątki.

Nikt nie może zagwarantować, że wątek zostanie zatrzymany. Tylko on sam może się zatrzymać.