关于Thread类的join()阻塞当前线程以等待子线程处理完毕疑问?
来源:8-4 如何实现处理线程的返回值
慕斯4415754
2019-06-01
老师,使用Thread类的join()阻塞当前线程以等待子线程处理完毕,您使用了t.join()来阻塞当前线程,但为什么没有去显示唤醒,而是等待子线程处理完毕?(您在讲线程状态中,没有设置Timeout参数的Thread.join()方法会进入无限期等待,需要被显示唤醒),期待您的解答,谢谢。
写回答
1回答
-
翔仔
2019-06-02
同学好,视频里调用没有参数的join去等待子线程处理完毕是符合预期的,不需要显示唤醒呢,我们可以看看它的源码
public final void join() throws InterruptedException { join(0); } public final synchronized void join(long millis) throws InterruptedException { long base = System.currentTimeMillis(); long now = 0; if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (millis == 0) { while (isAlive()) { wait(0); } } else { while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } } public final synchronized void join(long millis, int nanos) throws InterruptedException { if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (nanos < 0 || nanos > 999999) { throw new IllegalArgumentException( "nanosecond timeout value out of range"); } if (nanos >= 500000 || (nanos != 0 && millis == 0)) { millis++; } join(millis); }
其中
1. join() 和 join(long millis, int nanos) 最后都调用了 join(long millis)。
2. 带参数的 join() 都是 synchronized method。
3. join() 调用了 join(0),从源码可以看到 join(0) 不断检查当前线程(join() 所属的线程实例,非调用线程)是否是 Active。
4. join() 和 sleep() 一样,都可以被中断(被中断时,会抛出 InterrupptedException 异常);不同的是,join() 内部调用了 wait(),会出让锁,而 sleep() 会一直保持锁。
正因为会一直检查状态,如果被调用的线程一直是alive的话,调用join的线程会让出锁直至被调用的线程完成,就会接着执行,因此不需要显示唤醒呀
122019-06-03
相似问题