一、概念
sleep
線程進入阻塞狀態,不能得到CPU執行時間,只有等待時間夠長之后才會使線程重新進入可執行狀態。 調用sleep時線程不會釋放他的鎖標識。
wait
wait需和notify配合使用,線程調用wait后進入阻塞狀態。wait有兩個重載方法,一個是包含固定時長參數,另一個不包含固定時長參數。
- 包含固定時長參數時在等待時長超出或者調用notify都會使線程重新進入可執行狀態;
- 不包含固定時長參數的只有調用notify才會重新進入可執行狀態。
wait 和 notify需要使用在synchronized函數或塊中,當進入wait時,同步塊中的同步數據可以被其他線程使用。
二、區別
- 兩者最主要的區別在於:sleep 方法沒有釋放鎖,而 wait 方法釋放了鎖 。
- 兩者都可以暫停線程的執行。
- Wait 通常被用於線程間交互/通信,sleep 通常被用於暫停執行。
- wait() 方法被調用后,線程不會自動蘇醒,需要別的線程調用同一個對象上的 notify() 或者 notifyAll() 方法。sleep() 方法執行完成后,線程會自動蘇醒。或者可以使用 wait(long timeout)超時后線程會自動蘇醒。
- wait()方法的調用必須放在synchronized方法或synchronized塊中
三、擴展
notify
- notify()方法會喚醒一個等待當前對象的鎖的線程。 如果多個線程在等待,它們中的一個將會選擇被喚醒。這種選擇是隨意的。
- 被喚醒的線程是不能被執行的,需要等到當前線程放棄這個對象的鎖。 被喚醒的線程將和其他線程以正常的方式進行競爭,來獲得對象的鎖,沒有什么優先權。
- notify方法和wait一樣,是需要放在synchronized方法或synchronized塊中。
- 調用notifyAll()方法能夠喚醒所有正在等待這個對象的monitor的線程。
yield
Yeild只會使當前線程結束執行狀態,功能相當於提前讓線程的CPU時間使用完畢。當前的線程繼續進入可執行隊列中,所以有可能當前的線程會投入可執行隊列后會立即進行執行。Wait可以使低優先級的線程得到執行時間,但Yeild只會使同優先級的線程得到執行時間。
suspend
Suspend需和resume配套使用。Suspend使當前線程阻塞,且不會自動回復。只有調用resume才會使當前的線程恢復可執行狀態。