使用Join(或者自己实现Join)主线程被提前唤醒

来源:7-14 join注意点

Panda_io

2020-02-17

最近假期太长二刷的时候发现一个问题,请老师帮我看看。

public class JoinPrincipleException {
    public static void main(String[] args) throws InterruptedException {
        Thread mainThread = Thread.currentThread();
        Thread thread =  new Thread(()->{
            try {
                mainThread.interrupt();
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"执行完毕");
        });
        thread.start();
        System.out.println("开始等待子线程运行完毕");
        //thread.join();
        synchronized (thread){
            try {
                thread.wait();   //wait只有在synchronized代码块中才能运行
            } catch (InterruptedException e) {
                System.out.println("主线程被中断了!");
            }
        }
        System.out.println("所有子线程执行完毕");
    }
}

打印结果

第一阶段:

主线程进入waiting状态,子线程执行mainThread.interrupt();

主线程在wait状态下被中断,但是老师讲过:“必须要等到被唤醒后,并且拿到锁之后才能响应中断的,wait期间什么都做不了”

问题:
子线程对主线程进行中断后,立马进入sleep(10000) 10秒,所以这段时间子线程并没有执行完成,所以thread并没有调用 thread.notifyAll()这个方法来唤醒主线程。但是主线程却响应了中断,这与老师“必须要等到被唤醒后,并且拿到锁之后才能响应中断的,wait期间什么都做不了”这句话有些矛盾,或者是说main线程在子线程执行完成之前就已经得到唤醒,那么又是谁去唤醒的呢

图片描述
阶段二
10s后打印出 Thred-0执行完毕
图片描述
图片描述
确实如老师所说,wait()和sleep()响应中断的时候确实会被唤醒,以前只注意到sleep没注意到wait

写回答

1回答

悟空

2020-02-17

中断就是一种唤醒,讲中断原理那个小节的时候,分析cpp源码的时候讲过哈。

0
2
悟空
回复
Panda_io
恩,点赞
2020-02-17
共2条回复

线程八大核心+Java并发原理及企业级并发解决方案

完整的并发知识网络+丰富的工作内容分享+50余道并发高频面试题

2512 学习 · 939 问题

查看课程