Разница между interrupt(), interrupted() и isInterrupted()

Java задняя часть WeChat исходный код

1. Вывод первый

прерывание(): помечает поток, представленный объектом, вызывающим этот метод, маркером остановки, фактически не останавливая поток.

прервано(): получитьтекущий потоки очищает флаг состояния потока. является статическим методом.

isInterrupted(): получитьПолучить поток, представленный объектом, вызывающим метод, не очищает флаг состояния потока. является методом экземпляра.

Теперь мы подробно расскажем о каждом методе:

2. interrupt()

Во-первых, давайте воспользуемся методом interrupt() для наблюдения за эффектом Код выглядит следующим образом:

public class MainTest {
   @Test
   public void test() {
       try {
           MyThread01 myThread = new MyThread01();
           myThread.start();
           myThread.sleep(2000);
           myThread.interrupt();
       } catch (Exception e) {
           System.out.println("main catch");
           e.printStackTrace();
       }
   }
}

public class MyThread01 extends Thread {
   @Override
   public void run() {
       super.run();
       for (int i = 0; i < 500; i++) {
           System.out.println("i= " + i);
       }
   }
}

Выходной результат:

image

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

Итак, как мы узнаем этот стоп-сигнал? —— На этом этапе будут представлены следующие методы interrupted() и isInterrupted().

3. Прервано() и Прервано()

  • Объявление метода interrupted()public static boolean interrupted()

  • Объявление метода isInterrupted()public boolean isInterrupted()

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

Давайте сначала посмотрим на программу, которая использует interrupted().

@Test
public void test() {
      try {
          MyThread01 myThread = new MyThread01();
          myThread.start();
          myThread.sleep(1000);
//     7行: Thread.currentThread().interrupt(); // Thread.currentThread() 这里表示 main 线程
          myThread.interrupt();
          // myThread.interrupted() 底层调用了 currentThread().isInterrupted(true); 作用是判断当前线程是否为停止状态
          System.out.println("是否中断1 " + myThread.interrupted());
          System.out.println("是否中断2 " + myThread.interrupted());
      } catch (InterruptedException e) {
          System.out.println("main catch");
      }
  System.out.println("main end");
}

Выходной результат:

image

Из этого видно, что поток не останавливался, и это также подтверждает объяснение метода interrupted(): проверить, не был ли прерван текущий поток.Этот текущий поток является основным потоком, который никогда не прерывался, поэтому все результаты печати ложны.

Итак, как заставить основной поток иметь эффект прерывания? Закомментировав строку 8 выше и раскомментировав строку 7 и запустив ее, мы можем получить следующий вывод:

image

По результатам метод interrupted() действительно определяет, находится ли текущий поток (в данном случае основной поток) в остановленном состоянии, но почему второе логическое значение равно false? Мы сказали в начале - interrupted() проверяет, находится ли текущий поток уже в прерванном состоянии, и очищает флаг состояния после выполнения.

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

При первом вызове, с момента предыдущего выполненияThread.currentThread().interrupt();, что приводит к тому, что текущий поток помечается флагом прерывания, поэтому первый вызов метода interrupted() возвращает значение true. Поскольку у interrupted() есть функция очистки флага состояния, он вернет false при втором вызове метода interrupted().

Выше было введение в interrupted(), и, наконец, давайте посмотрим на метод isInterrupted().

Есть два различия между isInterrupted() и interrupted(): первое состоит в том, что они не имеют функции очистки флага состояния, потому что базовый параметр, передаваемый методу isInterrupted(), имеет значение false. Второй — это поток, представленный объектом, чей поток, по его мнению, вызывает метод, в данном случае это объект MyThread01.

Давайте изменим приведенный выше код, чтобы увидеть эффект:

@Test
public void test() {
   try {
       MyThread01 myThread = new MyThread01();
       myThread.start();
       myThread.sleep(1000);
       myThread.interrupt();
       // 修改了下面这两行。
       // 上面的代码是 myThread.interrupted();
       System.out.println("是否中断1 " + myThread.isInterrupted());
       System.out.println("是否中断2 " + myThread.isInterrupted());
   } catch (InterruptedException e) {
       System.out.println("main catch");
       e.printStackTrace();
   }
   System.out.println("main end");
}

Выходной результат:

image

Результат очевиден, потому что у isInterrupted() нет функции для очистки флага состояния, поэтому оба раза она выводит true.

Справочная статья:блог woo woo woo.cn на.com/happy плотно/afraid/54…

PS: Эта статья изначально была опубликована в публичном аккаунте WeChat «Не только Java».