1

Пожалуйста сначала увидеть этот фрагмент:Thread - Сон и прерывают

public static void main(String[] args) throws InterruptedException { 
    Thread anotherThread = new Thread(() -> { 
     Integer countB = 0; 
     while (true) { 
      try { 
       System.out.println("B count: " + ++countB); 
       Thread.sleep(2000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 
    anotherThread.start(); 

    Integer countA = 0; 
    while (true) { 
     System.out.println("A count: " + ++countA); 
     Thread.sleep(1000); 
    } 
} 

Это работает, как ожидалось. Я считаю, что countA составляет приблизительно 2x от countB.

Теперь я добавить одну строку в то время как внешнего контура:

public static void main(String[] args) throws InterruptedException { 
    Thread anotherThread = new Thread(() -> { 
     Integer countB = 0; 
     while (true) { 
      try { 
       System.out.println("B count: " + ++countB); 
       Thread.sleep(2000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 
    anotherThread.start(); 

    Integer countA = 0; 
    while (true) { 
     anotherThread.interrupt(); 
     System.out.println("A count: " + ++countA); 
     Thread.sleep(1000); 
    } 
} 

Основной поток прерывает anotherThread. После этого countA больше не 2x countB. Они всегда отличаются друг от друга.

Почему так? Как работает сон/прерывание?

+0

что вы считаете прерывание делает? Вы читали javadocs? –

+1

@ScaryWombat не груб, я думаю, что это действительно вопрос – Betlista

+1

@Betlista Что грубо? Я просто задаю два вопроса. Не зная, каковы ответы, я даже не могу ответить на вопрос. –

ответ

0

Это дополнение к Buddy's answer, который является правильным.

В первом случае у вас есть

B A 
. . 
. A 
. . 
B A 
. . 
. A 
. . 
B A 

, но с прерыванием он изменился:

B A (interrupts B, B continues in loop) 
B . 
. A (interrupts B again) 
B . 
. A 
B . 
. A 
B . 
. A 

вызывая B не ждать 2 секунды ...

+0

Спасибо. Теперь я понимаю. И, конечно же, я придумал вопрос из учебника Oracle Java – Boyang

3

В основном звонит interrupt просыпается поток от его sleep звонок. Как правило, вы прерываете поток, потому что хотите, чтобы он изящно закончил ... но в этом случае он просто проснулся, а затем продолжает движение в бесконечном цикле.

Заканчивать Документы для получения дополнительной информации: https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

0

Если вы прервали anotherThread он будет просыпаться от сна. Другими словами, он не спящий 2сек, а только 1сек, как ваш основной поток (countA).

Прерывание: Пробуждение нити, которая находится в состоянии sleep. Метод sleep (int) будет вызывать InterrruptedException, когда прерывание() вызывается, чтобы указать, что время не истекло.

0

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

Thread anotherThread = new Thread(() -> { 
    Integer countB = 0; 
    while (!Thread.currentThread().isInterrupted()) { 
     try { 
      System.out.println("B count: " + ++countB); 
      Thread.sleep(2000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
      Thread.currentThread().interrupt(); 
     } 
    } 
}); 

, то прерывание потока приведет к его завершению.

Прерывание вызова устанавливает флаг прерывания, когда поток спал и обнаруживает, что установлен флаг, тогда метод sleep генерирует прерывание Exception, также очищает флаг прерывания в потоке. Вызов прерывания по потоку в блоке catch необходим для восстановления значения флага. Затем, имея тест цикла while, флаг прерывания дает потоку возможность выйти.