undefined

Остановить бушующий поток: неофициальная версия

Java Core
6 уровень , 8 лекция
Открыта

— Привет, Амиго! Вот интересный вопрос, с которым ты уже столкнулся или столкнёшься в ближайшее время. А как остановить запущенную нить?

Допустим, пользователь отдал программе команду «загрузить файл из интернета». Главная нить создала для этого задания отдельную дочернюю нить, и передала ей объект, метод 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.

Главная нить завершает свою работу.

Нить часов завершает свою работу.

— Буду знать, спасибо, Элли.

Комментарии (161)
Чтобы просмотреть все комментарии или оставить свой,
перейдите в полную версию
Таймураз Вазиев 16 уровень, Казань
13 апреля 2021
вроде не проброшено исключение в примере
stepa113 20 уровень, Москва
6 февраля 2021
Непонятно, почему для остановки множества нитей нельзя сделать как в первом примере?
🦔 Виктор 20 уровень, Москва Expert
16 января 2021
Бельчонок Изи 31 уровень, Казань
13 января 2021
Где-то потоки запускаются прям в конструкторе, где-то в методе мейн. Может, кто-то знает, как правильней? Если посмотреть у Шилдта, то он запускает их в конструкторе.
Максим Дудин 23 уровень, Калининград
3 декабря 2020
так вот как работает Thread.sleep(10000);...тормозит основную нить...
Evgeny Vlasov 22 уровень, Москва
22 ноября 2020
В java мейн рутина если завершается - остальные могут продолжать работать? Или мейн рутина компилятором тушится ТОЛЬКО после того, как все остальные треды завершились?
Fregat 26 уровень, Днепр
15 ноября 2020
К вопросу о return - В конце каждого метода типа void по умолчанию стоит return. Не использовали break, т.к он выходит из цикла, и если бы после цикла был бы код, то он бы начал исполнятся. Явно использовали return сразу выходит из цикла и метода. return - выходи из метода break - выход из цикла
Regina Kazan 35 уровень, Казань
10 ноября 2020
в теории открываешь - вроде все так радужно и понятно. начинаешь разбирать задачу - типа предыдущей про самолеты - нифига не понятно, а именно - что за волотиль, что за синхронайзд переменные, господи... я то еще до сих пор не до конца понимаю эти this и super, а уже тут такое творится... сложнааааа. пытаюсь параллельно читать книги - там еще хуже.
Avrelio 38 уровень, Aveiro
22 октября 2020
как это изи
Николай Т. 29 уровень, Рязань
3 сентября 2020
Элли: Привет, Амино, как остановить запущенную нить? Амиго: Да, как? Элли: Никак, азазазаза!