1

請第一次看到這個片段:主題 - 睡眠和中斷

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約爲countB的2倍。

現在我一個行添加到外while循環:

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

你覺得中斷怎麼辦?你讀過javadoc嗎? –

+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

0

如果中斷anotherThread它會從睡眠中醒來。換句話說,它不會睡眠2秒,但只有1秒,比如你的主線程(countA)。

什麼中斷:它會喚醒處於狀態睡眠的線程。方法sleep(int)將拋出InterrruptedException中斷()被調用以指示未過去的時間。

0

中斷要求中斷線程進行合作,它必須查找已被中斷並處理它們的跡象。如果您將另一個線程更改爲:

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方法拋出一個InterruptedException異常,同時清除線程上的中斷標誌。爲了恢復標誌值,需要調用catch塊中的線程中斷。然後通過while循環測試檢查中斷標誌使線程有機會退出。