Как работает порядок выполнения прерываний в этой программе? - PullRequest
0 голосов
/ 07 июня 2019

Я читал реализацию прерывания в Java, но я не мог понять, как проходит управление?

Фрагмент кода:

public class Main implements Runnable
{

 Thread t;

 Main() 
{
  t = new Thread(this);
  t.start();
  t.interrupt();  
  if (!t.interrupted())
  {
  System.out.println("TRUE");
  }
}

 public void run() 
 {
  try 
  {   
   System.out.println("Thread is in running state");
   Thread.sleep(1000);

  } 
  catch (InterruptedException e) 
  {
   System.out.print(t.getName() + " interrupted");
  }
 }

 public static void main(String args[]) 
{
  new Main();
 }
}

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

Thread is in running state
Thread-0 interrupted
TRUE

Но это НЕПРАВИЛЬНО.

Правильный вывод:

TRUE
Thread is in running state
Thread-0 interrupted

Поэтому, пожалуйста, объясните, как работает этот порядок выполнения и почему?


Редактировать 1: Как уже отмечалось, вызов t.interrrupted() вводит в заблуждение, поэтому я изменил конструктор на:

 Main() 
{
  t = new Thread(this);
  t.start();
  t.interrupt();  
  if (!Thread.interrupted())
  {
  System.out.println("TRUE");
  }
}

Итак, теперь вывод:

TRUE
Thread is in running state
Thread-0 interrupted

Теперь вопросы,

  1. Поскольку поток находился в нерабочем состоянии при вызове t.interrupt (), что тогда делает t.interrupt () в этом случае?
  2. Почему печатается последняя строка вывода? Откуда оно получает прерывание, потому что t.interrupt был выполнен, когда поток находился в нерабочем состоянии.

Ответы [ 2 ]

3 голосов
/ 07 июня 2019

Во-первых, вы вызываете неправильный метод.

Как указано в другом ответе, interrupted() - это статический метод, который всегда проверяет состояние прерывания потока current . Если вы хотите проверить статус t, вам следует позвонить t.isInterrupted().

Во-вторых, вы должны помнить, что start() не гарантирует, что поток начнет выполнение немедленно. На самом деле это случается редко. Новый поток фактически начнет выполнение, только когда планировщик скажет ему об этом.

Итак, что происходит:

  • вы звоните start(), но поток на самом деле еще не запускается
  • вы проверяете не тот поток, поскольку текущий поток явно не прерывается
  • новый поток начинает работать и немедленно прерывается из-за более раннего interrupt() вызова

Что касается ответов на редактирование:

  • Вы исправили конструкцию, но неправильно. Он по-прежнему проверяет поток current , который не прерывается
  • печатается последняя строка, поскольку новый поток прерывает , поэтому при запуске он имеет флаг прерывания - он немедленно выдает исключение
2 голосов
/ 07 июня 2019
if (!t.interrupted())

Эта строка вводит в заблуждение.interrupted() - это статический метод, который проверяет, был ли прерван поток current , а не именованный поток.Было бы намного лучше, если бы было написано:

if (!Thread.interrupted())
...