【问题标题】:Java: for loop executes once even after interruption of current threadJava:即使在当前线程中断后,for循环也会执行一次
【发布时间】:2016-05-27 21:58:48
【问题描述】:

我是线程概念的新手。我试图中断 run() 中的当前线程。

基本上,我试图打印一个单词 5 次(在 for 循环中),中间有 2 秒睡眠。当我尝试在第二次循环执行之前中断线程时,我仍然会在第二次打印出这个词。

public void run()
{
try{
for(int i=0;i<=5;i++){
 //print word
 System.out.println(word);
 //sleep
  Thread.sleep(2000);
 //interrupt
  Thread.currentThread().interrupt();

 }
 } catch(InterruptedException e){
 System.out.println("sleep interrupted");
 }
}

但是,当我编译并运行代码时,我得到以下结果:

word
word
sleep interrupted

我希望这个词只打印一次,因为在循环到 for 循环的下一个实例之前调用了中断。我不明白为什么会同时抛出第二个单词和 InterruptedException “睡眠中断”..

我期待中断会抛出“睡眠中断”而不第二次打印这个词。

谢谢!

【问题讨论】:

  • 你不检查中断标志;所以打断什么也没做。 下次您调用sleep,然后它会检查标志并引发异常。
  • 扩展@BoristheSpider 的评论:要获得所需的行为,您必须从外部源(另一个线程)中断线程。
  • @Turing85 从外部源中断仍然不会立即中断。如果线程当前正在执行i++ 而另一个线程调用interrupt(),您仍然会看到相同的行为。
  • @Andreas 你是对的。确切地说,必须在第一次迭代中执行sleep(...) 之前或期间中断线程。这是一个我没有提到的沉默假设,但注意到它为时已晚,所以我无法编辑我的评论:)
  • 感谢大家向我解释!真的很感激..

标签: java multithreading interrupt


【解决方案1】:

阅读interrupt()的javadoc:

如果这个线程被阻塞 [...]

如果这个线程被阻塞 [...]

如果这个线程被阻塞 [...]

如果前面的条件都不成立,那么这个线程的中断状态将被设置

由于在您调用interrupt() 时您的线程没有被阻塞,它只是设置状态,而不会引发异常。

sleep() 方法然后检测中断状态并抛出异常。

【讨论】:

    【解决方案2】:
    • 第一次打印单词
    • 睡2秒
    • 调用中断()
    • 第二次打印字
    • 调用睡眠会引发 InterruptedException

    你想要的是

    for(int i = 0; i <= 5 && !Thread.currentThread().isInterrupted(); i++){
    

    【讨论】:

      【解决方案3】:

      原因是您在调用 interrupt() 时实际上并没有中断您的线程。

      因此,您的异常在其触发,在中断之后,当状态设置为中断时。在这种状态下,你是不允许睡觉的,所以你得到了异常。

      【讨论】:

        【解决方案4】:

        当你调用 Thread.currentThread().interrupt() 时,你设置了线程的中断标志,然后可以被更高级别的中断处理程序适当地使用。通常,人们在捕获 InterruptedException 时使用它,即在 catch 块内让调用者知道发生了中断。

        但是在这里,您使用它来退出 for 循环。当您第二次进入 Thread.Sleep() 时,程序会实现标志集。要手动阅读,

        试试这个

        for(int i=0;i<=5 && !Thread.currentThread().isInterrupted();i++)
        

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-10-14
        • 1970-01-01
        • 1970-01-01
        • 2015-03-04
        • 1970-01-01
        • 2019-11-24
        • 1970-01-01
        相关资源
        最近更新 更多