相同点
- 线程状态相同,都是阻塞状态
- 都会进入内核态
不同点
- wait()方法是Object类中的方法,sleep()是Thread类中的方法
- wait()需要结合synchronized关键字使用,直接使用会报错,sleep()可以直接使用,Thread.sleep()。
- wait()方法需要notify()或者notifyAll()去唤醒,sleep()则需要打断唤醒
- 线程进入wait()时,会释放锁,通过notify唤醒时,需要重新进入队列排队。sleep()会持有锁进行休眠,其他竞争锁的线程无法操作。
sleep()底层原理
sleep()方法是一个native方法,其本质是使用了os函数来告诉系统,未来的多长时间内,这个线程将不参与CPU的竞争,系统内核通过内部的计时器,来计算是否到达了唤醒时间,进而将线程唤醒,继续竞争CPU。
wait()的底层原理
synchronized关键字底层实现中,有一个WaitSet,用来存放wait的线程,线程调用wait会将持有的对象头的monitor释放,并记录执行到wait()的位置,然后唤醒时,将waiting的线程继续放到entryList的等待队列中,继续排队等待获取锁
wait()、notify()注意事项
wait()、notify()必须结合synchronized关键字来使用,且操作的必须是synchronized关键字之中的对象,如果在一个synchronized对象中唤醒别的锁对象,会报错
例如:
Object add = new Object();Object listen = new Object();synchronized (add){listen.notify();add.wait();}
会报错:
一句话总结:notify唤醒的是其所在锁所阻塞的线程
