Java 无法理解thread.interrupt()方法的行为

Java 无法理解thread.interrupt()方法的行为,java,multithreading,Java,Multithreading,我不明白为什么控制台是空的 真的,真的,我被打断了 但我认为结果是 是的,我被打断了!!真的 为什么结果和我想的不一样?谢谢 TL;DR:Thread#interrupt()方法不立即涉及InterruptedException异常,它只是将名为interrupt status的内部标志设置为true,然后受影响的线程检查该标志 中断机制是使用一个称为 中断状态。调用Thread.interrupt设置此标志。当 线程通过调用静态方法检查中断 Thread.interrupted,中断状态被清除

我不明白为什么控制台是空的

真的,真的,我被打断了

但我认为结果是

是的,我被打断了!!真的


为什么结果和我想的不一样?谢谢

TL;DR:
Thread#interrupt()
方法不立即涉及
InterruptedException
异常,它只是将名为interrupt status的内部标志设置为
true
,然后受影响的线程检查该标志

中断机制是使用一个称为 中断状态。调用Thread.interrupt设置此标志。当 线程通过调用静态方法检查中断 Thread.interrupted,中断状态被清除。非静态 Thread.isInterrupted,由一个线程用于查询 另一个的中断状态,不改变中断状态 旗帜


因此,在设置中断状态和抛出
InterruptedException
之间发生了一些最小的延迟,这解释了为什么打印
我被中断发生在对
Thread.isAlive()的两次调用之后;DR:
Thread#interrupt()
方法不立即涉及
InterruptedException
异常,它只是将名为interrupt status的内部标志设置为
true
,然后受影响的线程检查该标志

中断机制是使用一个称为 中断状态。调用Thread.interrupt设置此标志。当 线程通过调用静态方法检查中断 Thread.interrupted,中断状态被清除。非静态 Thread.isInterrupted,由一个线程用于查询 另一个的中断状态,不改变中断状态 旗帜

因此,在设置中断状态和抛出
InterruptedException
之间发生了一些最小的延迟,这解释了为什么打印
我被中断发生在对
Thread.isAlive()的两次调用之后。这是一个时间问题

如果主线程在
线程
实际终止之前继续并打印
thread.isAlive()
,它将打印
true
。您只需在第二个输出处放置一个断点并等待片刻,然后让程序继续,即可对此进行检查。对于第二个
isAlive
检查,它将打印
false

根据主线程和其他线程之间的上下文切换,程序的输出可能会不时有所不同

实际上,在查询线程的状态时,您甚至不能确定您的第二个线程是否已经处于睡眠状态。如果要使线程的执行顺序相互依赖,则需要在线程之间引入一些同步。

这是一个计时问题

如果主线程在
线程
实际终止之前继续并打印
thread.isAlive()
,它将打印
true
。您只需在第二个输出处放置一个断点并等待片刻,然后让程序继续,即可对此进行检查。对于第二个
isAlive
检查,它将打印
false

根据主线程和其他线程之间的上下文切换,程序的输出可能会不时有所不同


实际上,在查询线程的状态时,您甚至不能确定您的第二个线程是否已经处于睡眠状态。如果要使线程的执行顺序相互依赖,则需要在线程之间引入一些同步。

谢谢您的回答!!我注意到你是新来的,所以如果你认为答案对你有帮助,你可以验证它;)谢谢你的回答!!我注意到你是新来的,所以如果你认为答案对你有帮助,你可以验证它;)我在第二个输出处设置了一个断点。准确地说,second out.print显示为false。感谢您的建议。我在第二个输出处设置了一个断点。准确地说,second out.print显示为false。感谢您的建议。线程在不同步时“并行”运行。“并行”意味着不能保证事情在不同线程中发生的顺序。您的第二个线程不可能在第一个线程中断之前打印“我被中断了”——这是一个同步的例子——但是您的程序允许println()调用和第二个
thread.isAlive
println并行进行。也就是说,不能保证这些事情中的哪一个会首先发生。线程在不同步时“并行”运行。“并行”意味着不能保证事情在不同线程中发生的顺序。您的第二个线程不可能在第一个线程中断之前打印“我被中断了”——这是一个同步的例子——但是您的程序允许println()调用和第二个
thread.isAlive
println并行进行。也就是说,无法保证这些事情中的哪一件会首先发生。
public static void main(String[] args) {
    Thread thread = new Thread(new Runnable() { 
        public void run() { 
            try { 
                Thread.sleep(99999); 
            } 
            catch(InterruptedException e) { 
                System.out.println("I'm interrupted!!"); 
            } 
         } 
    }); 

  thread.start();
  out.print(thread.isAlive()+" ");
  thread.interrupt(); 
  out.print(thread.isAlive()+" "); 
}