【问题标题】:Does a thread need to be in a RUNNABLE state before it can be interrupted?线程是否需要处于 RUNNABLE 状态才能被中断?
【发布时间】:2017-11-11 12:48:17
【问题描述】:

java中的线程在被中断方法中断之前是否必须处于就绪状态? 我试图通过在下面输入上面给出的代码来检查这一点。

class MyThread extends Thread
{
    public void run() {
        try
        {
            for(int i =0;i<10;i++) {
               System.out.println("I am lazy thread");
               Thread.sleep(2000);
            }
        }
        catch(InterruptedException e) {
            System.out.println("I got interrupted");
        }
    }
}

public class SleepAndInterruptDemonstrationByDurga {
    public static void main(String[] args) {
       MyThread t= new MyThread();
       t.start();
       t.interrupt();
       System.out.println("End of main thread");
    }
}

即使尝试了很多次,我得到的输出始终是下面的输出

End of main thread
I am lazy thread
I got interrupted

为什么不能输出

I am lazy thread
I got interrupted
End of main thread

从代码可以看出,中断方法是由主线程首先调用的。最后我想问一下,在线程启动之前首先执行中断调用时,是否有任何可能的情况?

【问题讨论】:

    标签: java multithreading interrupt interruption


    【解决方案1】:

    java中的线程是否必须在它之前处于就绪状态 被中断方法打断了?

    interrupt 方法并没有真正中断线程。它只设置调用它的线程的中断状态。也就是说,如果您反转对interrupt 方法和start 方法的调用,您会注意到Thread 不会被中断。

    MyThread t = new MyThread();
    t.interrupt();
    t.start();
    

    这应该确认要使Thread.interrupt 方法对Thread 产生影响,最低要求是在Thread 上调用startinterrupt 方法之前。

    注意 没有称为就绪状态的线程状态。您指的是 RUNNABLE 状态,这表明在 Thread 上调用了 start

    【讨论】:

      【解决方案2】:

      这里发生的是

      1) 您启动的线程需要时间准备好运行,因此“主线程结束”可能会首先打印,但这不能保证。

      2) 在新线程完成启动之前设置中断标志,但在线程休眠之前不会检查该标志的状态。当您在仅设置标志的线程上调用中断时,除非您调用诸如 sleep 或 isInterrupted 之类的东西,否则该线程不会做任何响应。所以“我很懒线程”会在“我被打断”之前出现。

      中断是自愿的,需要被中断线程的配合。线程在运行之前不能对中断标志状态进行操作,因为某些代码必须检查该标志并对其进行操作。

      【讨论】:

      • 感谢您的回复,但我要问的是,进行中断调用的线程是否需要在调用 sleep 之前处于就绪状态。然后在进入中断状态之前,线程必须处于睡眠状态。因此,为了使线程中断,线程必须首先处于就绪状态。不是吗?
      • @Deep:这样更好吗?
      • 此外,有时可能会在代码中的 t.start() 之后首先调用子线程
      • 要让线程作用于中断状态,它必须正在运行。不知道该怎么说清楚。
      • 是的......这就是我想听到的线程被中断......它必须在中断被调用之前处于就绪状态......我明白了......谢谢
      【解决方案3】:

      如果你想让主线程等待另一个线程完成它必须做的事情,你应该做t.join()

      【讨论】:

        【解决方案4】:

        System.out.println("End of main thread"); 行可能是在线程启动之前执行的。在我的电脑上,程序可能会首先打印End of main thread,第二个或最后一个。

        至于您的问题,Java 线程没有称为“就绪”或“中断”的状态(请参阅documentation)。 Thread.interrupt() 只是导致线程将其状态更改为“TERMINATE”。

        另见here:

        中断一个不活跃的线程不需要有任何效果。

        【讨论】:

          猜你喜欢
          • 2018-12-31
          • 2017-06-27
          • 1970-01-01
          • 2015-09-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-03-02
          相关资源
          最近更新 更多