一张图搞清楚 wait、sleep、join、yield 四者区别,面试官直接被征服!
写在开头
在线程的生命周期中,不同状态之间切换时,可以通过调用 sleep()、wait()、join()、yield()等方法进行线程状态控制,针对这一部分知识点,面试官们也会做做文章,比如问你这些方法的作用以及之间的区别。
那么今天我们就一起来总结一下这几个方法的作用及区别,先画一个思维导图梳理一下,便于理解与记忆,争取在被问到这个点时彻底征服面试官!(图片可保存常看哈
)
sleep()
sleep()是 Thread 类中的一个静态本地方法,通过设置方法中的时间参数,使调用它的线程休眠指定时间,线程从 RUNNING 状态转为 BLOCKED 状态,这个过程中会释放 CPU 资源,给其他线程运行机会时不考虑线程的优先级,但如果有同步锁则 sleep 不会释放锁即其他线程无法获得同步锁,需要注意的是 sleep()使用时要处理异常。休眠时间未到时,可通过调用 interrupt()方法来唤醒休眠线程。
【代码示例 1】
为什么 sleep()放在 Thread 类中
答:因为 sleep 是线程级别的休眠,不涉及到对象类,只是让当前线程暂停,进入休眠状态,并不释放同步锁资源,也不需要去获得对象锁。
wait()
wait() 是 Object 类的成员本地方法,会让持有对象锁的线程释放锁,进入线程等待池中等待被再次唤醒(notify 随机唤醒,notifyAll 全部唤醒,线程结束自动唤醒)即放入锁池中竞争同步锁,同时释放 CPU 资源,它的调用必须在同步方法或同步代码块中执行,也需要捕获 InterruptedException 异常。
【代码示例 2】
为什么 wait()是 Object 的方法
答:每个对象都拥有对象锁,wait 的作用是释放当前线程所占有的对象锁,自然是要操作对应的 Object 而不是 Thread,因此 wait 要放入到 Object 中。
join()
join()同样是 Thread 中的一个方法,调用 join 的线程拥有优先使用 CPU 时间片的权利,其他线程需要等待 join()调用线程执行结束后才能继续执行,探索其底层会发现,它的底层是通过 wait()进行实现,因此它也需要处理异常。
【代码示例 3】
我们跟进 join()方法内部会发现,其底层主要通过 wait()实现,其中参数代表等待当前线程最多执行 millis 毫秒,如果 millis 为 0,则会一直执行,直至完成,其他线程才会继续向下;
【源码示例 1】
yield()
yield()是 Thread 的一个静态方法,它的调用不需要传入时间参数,并且 yield() 方法只会给相同优先级或更高优先级的线程运行的机会,并且调用 yield 的线程状态会转为就绪状态,调用 yield 方法只是一个建议,告诉线程调度器我的工作已经做的差不多了,可以让别的线程使用 CPU 了,没有任何机制保证采纳。所以可能它刚让出 CPU 时间片,又被线程调度器分配了一个时间片继续执行了。使用时不需要处理异常。
【代码示例 4】
输出:
总结
上文中,我们结合代码示例,对这个四个方法进行了详细介绍,下面我们以 sleep()为参照,进行对比总结:
(1)sleep()与 wait()的区别?
sleep() 是 Thread 类的静态本地方法;wait() 是 Object 类的成员本地方法;
JDK1.8 sleep() wait() 均需要捕获 InterruptedException 异常;
sleep() 方法可以在任何地方使用;wait() 方法则只能在同步方法或同步代码块中使用;
sleep() 会休眠当前线程指定时间,释放 CPU 资源,不释放对象锁,休眠时间到自动苏醒继续执行;wait() 方法放弃持有的对象锁,进入等待队列,当该对象被调用 notify() / notifyAll() 方法后才有机会竞争获取对象锁,进入运行状态。
(2)sleep()与 yield()的区别?
sleep() 方法给其他线程运行机会时不考虑线程的优先级;yield() 方法只会给相同优先级或更高优先级的线程运行的机会;
sleep() 方法声明抛出 InterruptedException;yield() 方法没有声明抛出异常;
线程执行 sleep() 方法后进入超时等待状态;线程执行 yield() 方法转入就绪状态,可能马上又得得到执行;
sleep() 方法需要指定时间参数;yield() 方法出让 CPU 的执行权时间由 JVM 控制。
(3)sleep()与 join()的区别?
JDK1.8 sleep() join() 均需要捕获 InterruptedException 异常;
sleep()是 Thread 的静态本地方法,join()是 Thread 的普通方法;
sleep()不会释放锁资源,join()底层是 wait 方法,会释放锁。
文章转载自:JavaBuild
评论