Подтвердить что ты не робот

Как убить поток, который имеет некоторое время (правда)?

Я пытаюсь закрыть весь поток в моем потоке.

Обычно я стараюсь:

        while(!Thread.currentThread().isInterrupted()) {...

Чтобы закрыть цикл while...

Но у меня есть один Thread, который состоит только из

        while(!Thread.currentThread().isInterrupted()) {//which is true

Вот как я закрываю потоки:

pool.shutdownNow();

Итак, как бы вы закрыли такой поток?

4b9b3361

Ответ 1

Вы можете добавить volatile boolean flag.

public class Worker implements Runnable {

    volatile boolean cancel = false;
    @Override
    public void run() {

        while (!cancel) {
            // Do Something here
        }
    }

    public void cancel() {
        cancel = true;
    }
}

Теперь вы можете просто позвонить

worker.cancel();

Update:

Из документа Java shutdownNow()

Попытка остановить все активное выполнение задач, приостанавливает обработку ожидающих задач и возвращает список задач, ожидающих выполнения.

здесь нет никаких гарантий, кроме лучших попыток прекратить обработку, активно выполняющую задачи. Например, типичные реализации будут отменены с помощью Thread.interrupt(), поэтому любая задача, которая не отвечает на прерывания, может никогда не прерывать.

Таким образом, либо вам нужно будет определить свою политику прерывания, сохранив прерывания

  catch (InterruptedException ie) {
     // Preserve interrupt status
     Thread.currentThread().interrupt();
   }

Ответ 2

Вместо этого вы можете использовать сам созданный флаг как условие для цикла while.

public class MyClass implements Runnable
{

    private volatile boolean running = true;

    public void stopRunning()
    {
        running = false;
    }

    public void run()
    {
        while (running)
        {

        }
        // shutdown stuff here
    }

}

Теперь, чтобы остановить его, просто позвоните:

myClassObject.stopRunning();

Это позволит нормальному завершению кода.

Ответ 3

Если вы реализовали это, как вы описали, он должен просто работать.

Когда вы вызываете pool.shutdownNow(), предполагается прервать все текущие рабочие потоки. Предполагая, что специфичные для приложения методы run() проверяют прерванный флаг и завершают себя, когда они находят его установленным, ваши потоки должны завершаться.

В действительности нет необходимости добавлять другой механизм, используя флаг ad hoc cancel... или некоторые такие.


Кстати, есть несколько причин, по которым interrupt() лучше, чем специальная аннулирование:

  • Стандартные API, такие как ExecutorService, используют его.
  • Различные низкоуровневые API-методы, такие как sleep, wait, join и некоторые методы ввода-вывода чувствительны к нему.

Ответ 4

Если вы используете реализацию java.util.concurrent ExecutorService, то он обязательно отправит сигнал interrupt всем потокам в пуле потоков. Проблема с вашей задачей-изгоем может заключаться в том, что цикл на самом деле не повторяется, а блокирует где-то внутри, поэтому статус interrupted вообще не проверяется.

Еще одна проблема, которая может возникнуть у вас: цикл while запускает некоторый код, который ловит InterruptedException без правильной обработки, эффективно проглатывание сигнала прерывания. Это обычная ошибка кодирования и в большинстве случаев из-за уродливой правды, которую проверяет InterruptedException.