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