— Привіт, Аміго! Ось цікаве питання, з яким ти вже зіткнувся чи зіткнешся найближчим часом. А як зупинити запущений потік?

Припустимо, користувач віддав програмі команду «завантажити файл з інтернету». Головний потік створив для цього завдання окремий дочірній потік і передав йому об'єкт, метод run якого містить усі необхідні дії для завантаження файлу.

А тут користувач взяв і передумав. Не хоче він скачувати цей файл. Як скасувати завдання і зупинити потік?

— Як?

— Ніяк. Це і є найзагальніша і найправильніша відповідь. Потік зупинити не можна, він може зупинитися лише сам.

Але можна дати потоку сигнал, повідомити його якимось чином, що роботу більше виконувати не потрібно, і йому потрібно завершитись. Так само, як головний потік завершується разом із виходом з методу main, щоб завершити дочірній потік, він має закінчити виконання методу run.

— Як краще за все це зробити?

— Можна завести якусь змінну, наприклад типу boolean. Якщо вона true – потік працює. Якщо ж вона стала false – потік повинен завершитись. Наприклад, так:

Код Опис
class Clock implements Runnable
{
public void run()
{
while (true)
{
Thread.sleep(1000);
System.out.println("Tik");

if (!ClockManager.isClockRun)
return;
}
}
}
Клас Clock (годинник) буде вічно писати в консолі раз на секунду слово «Tik»

Якщо змінна ClockManager.isClockRun дорівнює false – метод run завершиться.

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;
}

}
Головний потік, запускає дочірній потік – годинник, які повинен працювати вічно.

Чекає 10 секунд і подає годиннику сигнал на завершення.

Головний потік завершує свою роботу.

Потік годинника завершує свою роботу.

— А якщо ми маємо кілька потоків, що тоді?

— Тоді краще завести таку змінну для кожного потоку. Найзручніше додати її прямо до класу. Можна додати туди змінну boolean isRun. Хоча краще додати змінну boolean isCancel, яка прийматиме значення true, якщо завдання скасовано.

Код Опис
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");
}
}
}
Клас Clock (годинник) писатиме в консолі раз на секунду слово «Тік», поки змінна isCancel дорівнює false.

Коли змінна isCancel буде дорівнювати true, метод run завершиться.

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

Thread.sleep(10000);
clock.cancel();
}
Головний потік, запускає дочірній потік – годинник, який має працювати вічно.

Чекає 10 секунд і скасовує завдання викликом методу cancel.

Головний потік завершує свою роботу.

Потік годинника завершує свою роботу.

— Знатиму, дякую.