线程控制方法之wait和sleep的区别
wait()和sleep()都是Java线程控制方法,但存在明显区别:
- 所属与调用:wait()属Object类,需synchronized调用;sleep()属Thread类,可随意调用。
- 锁处理:wait()释放锁,进入等待状态;sleep()不释放锁,仅暂停执行。
- 唤醒机制:wait()需notify()或notifyAll()唤醒;sleep()自动苏醒。
- 用途:wait()多用于线程间通信;sleep()用于暂停执行。
- 异常:两者都可能抛出InterruptedException。
总结:wait()释放锁并等待唤醒,用于线程通信;sleep()不释放锁且自动苏醒,用于暂停执行。
public class ThreadDemo25 {public static void main(String[] args) {Object locker=new Object();Thread t1=new Thread(()->{synchronized (locker){System.out.println("wait之前");try {locker.wait();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("wait之后");}});Thread t2=new Thread(()->{try {Thread.sleep(5000);synchronized (locker){System.out.println("notify之前");locker.notify();System.out.println("notify之后");}} catch (InterruptedException e) {e.printStackTrace();}});t1.start();t2.start();}
}
t2的notify()唤醒t1之后,只有等t2执行完自己的,释放锁之后,t1才能继续。所以先打印notify之后,再打印wait之后
t2 sleep结束之后,由于t1是wait状态,锁是释放的,t2就能拿到锁。
接下来打印t2 notify之前,执行notify操作,这个操作就能唤醒t1(此时t1就从WAITING状态恢复回来了)
但是由于t2此时还没有释放锁呢,t1 WAITING恢复之后,尝试获取锁,就可能会出现一个小小的阻塞,这个阻塞是由于锁竞争引起的。(肉眼很难看到BLOCKED状态,这个状态的变换是非常快的)
t2执行完t2 notify之后,释放锁,t2执行完毕,t1的wait就可以获取到锁了,继续执行打印t1 wait之后。