为了账号安全,请及时绑定邮箱和手机立即绑定

将run()里面的停顿时间改为是sleep()后,当主线程执行thread.interrupt()的疑问

将run()里面停顿时间改为是sleep()后,当主线程执行thread.interrupt()后,this.isInterrupted()的值为ture,那么while语句应该停止,为什么还会执行Thread.sleep()从而抛出异常?视频8分钟开始那里

正在回答

6 回答

薇辣酱 说得对, 是概率问题,子线程中while (!this.isInterrupted()) 这句话运行的时间非常短,子线程的绝大部分时间都在Thread.sleep(xxxx);这句话上,所以在主线程中将子线程中断的时候(主线程执行thread.interrupt()的时候),子线程有极大的概率处于sleep中,然后就会报sleep中断错误(sleep interrupted)。


简单的验证:

在子线程的sleep语句前后各加一个输出,比如“子线程将睡眠XX秒”和“子线程睡眠结束”,然后你会发现异常都出现在“子线程将睡眠XX秒”这句后面,然后没有出现相匹配的“子线程睡眠结束”,也就是说主线程在将子线程中断的时候,子线程都处于sleep的状态(绝大部分时候)。

处于非sleep的状态如果真的试出来了,应该是会出现“子线程将睡眠XX秒”和“子线程睡眠结束”,然后子线程退出循环。

0 回复 有任何疑惑可以回复我~

我想明白了,因为thread是从上一次停下来的位置开始运行的,不是从while (!this.isInterrupted())这里开始。而sleep占用了while循环大多数时间,所以上次大概率是在sleep()这里停的。

所以重新运行的时候,一开始就抛出了InterruptedException异常,同时this.isInterrupted()被置为false。然后while循环就一直运行下去了。

我将run循环内容做了一些修改,你可以看的更清楚。

public void run() {

    int i = 0;

    while (!this.isInterrupted()) {

        System.out.println(i);

        try {

            Thread.sleep(4000);

         } catch (InterruptedException e) {

            e.printStackTrace();

            System.out.println(i+1000);

        }

        System.out.println(i);

        i++;

    }

}

输出为:

Starting Thread...

0

Interrupting Thread...

java.lang.InterruptedException: sleep interrupted

at java.lang.Thread.sleep(Native Method)

at WrongWayStopThread.run(WrongWayStopThread.java:28)

1000

0

1

1

2

2

3

Stopping Application...


2 回复 有任何疑惑可以回复我~

我也没弄明白这个问题,求解答。。。

0 回复 有任何疑惑可以回复我~

this.isInterrupted()是测试线程的状态是否是interrupted的。

这个状态时由thread.interrupt()方法来置位的,但是thread.interrupt()方法置位为interrupted状态的前提是线程处于非阻塞状态,否则thread.interrupt()只会把interrupted清除并且抛出异常。

因为这里调用Thread.sleep()使线程处于阻塞状态,所以线程非但没有被置为interrupted,反而抛出了异常。


while循环的执行大部分时间应该是在Thread.sleep()上的,几乎不可能在Thread.sleep()刚好结束而还没有进行while(true)判断的时候thread.interrupt()置位为interrupted状态

1 回复 有任何疑惑可以回复我~

thread.interrupt()方法的作用是唤醒阻塞的线程,并抛出异常。当sleep后,线程阻塞,thread.interrupt()方法执行后,线程又被唤醒并抛出异常。因为线程被唤醒,所以this.isInterrupted()的值为false,while语句继续

2 回复 有任何疑惑可以回复我~

先抛出的一场,然后重置变量

0 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消

将run()里面的停顿时间改为是sleep()后,当主线程执行thread.interrupt()的疑问

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信