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循环测试检查中断标志使线程有机会退出。