- sleep与wait
我们可以从源码看出基本的差别:
- sleep是Thread下面的一个方法,而wait是Object下面的一个方法
- sleep()方法可以在任何地方使用。
- wait()方法只能在synchronized方法或者synchronized块中使用。
但它们本质上的区别则在于:
- Thread.sleep只会让出CPU,但是不会导致锁行为的改变。
- Object.wait不仅让出CPU,还会释放已经占有的同步资源锁。
- notify与notifyAll
首先,notify和notifyAll都可以去唤醒正在wait的线程。
紧接着,我们需要明白两个概念,在Java虚拟机中运行程序的每个对象来说,都有两个池:锁池(EntryList)和等待池(WaitSet)
- 锁池(EntryList)
假设线程A已经拥有了某个对象(不是类)的锁,而其他线程B、C想要调用这个对象的被同步锁包裹起来的方法,由于BC线程需要在调用方法之前先拥有解除锁的key,而这个key又恰巧被A占有,那么就会陷入阻塞状态等待锁的释放,而等待的期间,就处于该对象的锁池。
- 等待池(WaitSet)
如果线程A调用了某个对象wait方法,那么线程A就会释放该对象的锁,同时线程A就进入到了该对象的等待池中,进入到等待池中的线程不会去竞争该对象的锁。
那么,notify与notifyAll真正的区别在哪呢?
notifyAll会让所有处于等待池的线程全部进入锁池去竞争获取锁的机会,而notify只会随机选取一个处于等待池中的线程进入锁池去竞争获取锁的机会。