对比分析Java中的各个线程相关的wait()、notify()、sleep()、interrupt()方法
方法简述
Thread类
- sleep:暂停当前正在执行线程
静态方法
- join:等待调用该线程对象join方法执行结束
- yield:暂停当前正在执行的线程,让出cpu执行权,让其他线程执行,Thread类的
静态方法
。 - interrupt:中断线程,当线程调用wait,join,sleep方法时中断线程,并抛出interruptException/ClosedByInterruptException异常。
Object类
- wait:暂停当前执行的线程,直到调用notify,notifyAll或者超时时,退出等待。
- notify:调用对象上notify方法时,会唤醒在该对象上等待的一个线程。
- notifyAll:调用对象上的该方法时,会唤醒在该对象上等待的所有线程。
详细分析:
sleep VS wait
sleep()和wait()方法都是暂停当前正在执行的线程,出让CPU资源。
方法 | 所属类 | 方法类型 | 锁 | 解除方法 | 场景 | 用途 |
---|---|---|---|---|---|---|
sleep | Thread | 静态方法 | 不释放锁 | timeout,interrupt | 无限制 | 线程内控制 |
wait | Object | 普通方法 | 释放锁 | timeout,notify,notifyall,interrupt | synchronized修饰的同步代码块 | 线程间通信 |
wait && notify
调用对象的wait()、notify()、notifyAll()方法的线程,必须是作为此对象监视器的所有者。常见的场景便是就是synchronized关键字的语句块内部使用这3个方法,如果直接在线程中使用wait()、notify()、notifyAll()方法,那么会抛出异常IllegalMonitorStateException,抛出的异常表明某一线程已经试图等待对象的监视器,或者试图通知其他正在等待对象的监视器而本身没有指定监视器的线程。。
调用wait()方法的线程,在调用该线程的interrupt()方法,则会重新尝试获取对象锁。只有当获取到对象锁,才开始抛出相应的异常,则执行该线程之后的程序。
interrupt
interrupt()方法的工作仅仅是改变中断状态,并不是直接中断正在运行的线程。中断的真正原理是当线程被Object.wait(),Thread.join()或sleep()方法阻塞时,调用interrupt()方法后改变中断状态,而wait/join/sleep这些方法内部会不断地检查线程的中断状态值,当发现中断状态值改变时则抛出InterruptedException异常;对于没有阻塞的线程,调用interrupt()方法是没有任何作用。
yield
yield()方法使当前线程出让CPU执行时间,当并不会释放当前线程所持有的锁。执行完yield()方法后,线程从Running状态转变为Runnable状态,既然是Runnable状态,那么也很可能马上会被CPU调度再次进入Running状态。
网友评论