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只是會隨機選取一個處於等待池中的線程進入鎖池去競爭獲取鎖的機會。