Java Thread.stop() vs Thread.interrupt()

У меня есть следующий код:

renderThread = new Thread(new Runnable() {

    @Override
    public void run() {
        for (int i = 0; i < 10000000; i++) {
            System.out.println("Number: " + i);
        }
    }
});

renderThread.start();

try {
    Thread.sleep(100);
} catch (InterruptedException ex) {
    ex.printStackTrace();
}

renderThread.interrupt(); //It should stop, but it does not stop.

renderThread.interrupt() не прерывает поток, он продолжает работать. Если я заменил renderThread.interrupt() на .stop(), то поток остановится. Однако .stop() устарел. Тогда, каков правильный способ остановки потока, если stop устарел и interrupt не работает?

Ответы

Ответ 1

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

void run()
{
    while(!Thread.interrupted())
    {
        //Do something
    }
}

Просто потому, что вы вызываете прерывание, это не означает, что поток остановится немедленно или вообще. Это зависит от того, что находится в функции run.

Ответ 2

Чтобы действительно толкнуть точку, почему вы не должны использовать Thread.stop()?

Недавно Дуг Лея упомянул, что Thread.stop будет первым де-реализованным методом для Java приступить к Java 8.

Его ответ на этот комментарий от кого-то:

Кроме того, синхронизируется еще одна синхронизация - она ​​обрабатывает асинхронные прерывания потоков (I.e. thread.stop()). Я знаю, что stop() устарели и все, но вы никогда не знаете.

Был:

Но вы знаете! Начиная с JDK8, Thread.stop действительно ушел. Это первый устаревший метод, который фактически был отменен. Это сейчас просто бросает UnsupportedOperationException.

http://cs.oswego.edu/pipermail/concurrency-interest/2013-December/012028.html

Ответ 4

Все, что вам нужно сделать, чтобы прервать текущий поток или завершить выполняющийся процесс потока, - это добавьте инструкцию ниже в блок catch

try
{
   Thread.sleep(4000);
   System.out.println("VAS CONSULTING")
}
catch(InterruptedException e)
{
   //Stop printing out VAS CONSULTING
   return;  /*This will terminate the thread*/
}

также, если метод, который не выдает прерывание, не используется в методе запуска вы можете сделать это для обработки прерывания потока или прекращения потока

@Override
public void run()
{

   System.out.println("VAS CONSULTING");
   if(Thread.Interrupted())
   {
     doSomethingElse();//process something else within the thread
    return; //Terminates the current Thread
   }

}

Я надеюсь, что это поможет вам или кому-то еще.

Ответ 5

renderThread.interrupt() не прерывает поток, он продолжается для запуска.

  • Если поток выполняется и interrupt() вызывается, он устанавливает статус прерывания.
  • Если этот поток заблокирован при вызове одного из методов wait класса Object или методов Thread.join и Thread.sleep этого класса, тогда его статус прерывания будет очищен, и он получит InterruptedException.

Например:

Thread t = new Thread()
      {
          public void run()
          {
              try {
                  for(int i=0; i<10000;i++)
                      System.out.println("Is interrupTed? "+this.isInterrupted());

                  Thread.sleep(200);
              } catch (InterruptedException ex) {
                  Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
              }

          }
      };
      t.start();
      t.interrupt();
    }

В приведенном выше коде я использовал цикл for, чтобы перехватить флаг interrput с помощью isInterrupted() и распечатать его. При вызове t.interrupt() isInterrupted() вернет true, который вы увидите в консоли. Как только он достигнет Thread.sleep(miliTime), вы увидите, что InterruptedException пойман, который был выброшен, как описано выше.

Остановка потока:

вы можете использовать этот флажок isInterrupted(), если на него был вызван interrupt() и вернуться из выполнения:

Например:

Thread t = new Thread()
      {
          public void run()
          {
              long executeTime = System.currentTimeMillis() ;
              int i = 0;    
              for(; i<10000 && !this.isInterrupted();i++)
                      System.out.println("Is interrupted? "+this.isInterrupted());

               System.out.println("Was Interrupted? "+this.isInterrupted()
                                  +" after cycle: "+ i);
               System.out.println("Time it gets Executed: "
                                  +(System.currentTimeMillis() - executeTime+" ms"));

          }
      };
      t.start();
        try {
            Thread.sleep(200);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
      t.interrupt();

При запуске приведенного выше кода: я отправил основной поток в режим сна для 200 внутри статической основной функции, чтобы запустить запущенный поток t для запуска в течение некоторого времени. Затем я вызвал t.interrupt() на нем, который заставляет цикл for останавливаться и печатать вывод следующим образом:

Was Interrupted? true after cycle: 1477
Time it gets Executed: 258 ms

Что указывает, что цикл for имеет 1148 итерацию до t.interrupt(); в функции main.

Подробнее см. документацию Thread.interrupt().