sleep(),wait(),yield(),notify()
sleep(),wait(),yield() 的區別
sleep方法和yield方法是Thread類的方法,wait方法是Object的方法。
sleep 方法使當前運行中的線程睡眼一段時間,進入不可運行狀態,這段時間的長短是由程序設定的,不會釋放鎖標志。
wait方法調用后,線程會放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象調用notify()方法后本線程才進入對象鎖定池準備獲取對象鎖進入運行狀態。
yield 方法使當前線程讓出CPU占有權,但讓出的時間是不可設定的。yield()也不會釋放鎖標志。
yield()方法對應了如下操作: 先檢測當前是否有相同優先級的線程處于同可運行狀態,如有,則把 CPU 的占有權交給此線程,否則繼續運行原來的線程。所以yield()方法稱為"退讓",它把運行機會讓給了同等優先級的其他線程。
sleep方法允許較低優先級的線程獲得運行機會,但yield()方法執行時,當前線程仍處在可運行狀態,所以不可能讓出較低優先級的線程些時獲得CPU占有權。 在一個運行系統中,如果較高優先級的線程沒有調用 sleep 方法,又沒有受到 I/O阻塞,那么較低優先級線程只能等待所有較高優先級的線程運行結束,才有機會運行。
yield()只是使當前線程重新回到可執行狀態,所以執行yield()的線程有可能在進入到可執行狀態后馬上又被執行。所以yield()只能使同優先級的線程有執行的機會。
wait()與notify()的關系與應用
看以下代碼
public class WaitTest {public int flag=10;public static void main(String[] args) {WaitTest wait = new WaitTest();new Thread(new Runnable(){public void run(){wait.method1();}}).start();new Thread(new Runnable(){public void run(){wait.method2();}}).start();}public void method1(){System.out.println("method 1 is running");try{synchronized(this){System.out.println("method 1 is into lock");while(flag>0){this.wait();System.out.println("method 1 get notify");}System.out.println("method 1 is out lock");}}catch(InterruptedException e){e.printStackTrace();}System.out.println("method 1 is end");}public void method2(){System.out.println("method 2 is running");while(flag>0){try{synchronized(this){flag--;this.notify();}Thread.sleep(100);}catch(InterruptedException e){e.printStackTrace();}}System.out.println("method 2 is end");} } 輸出: method 1 is running method 1 is into lock method 2 is running method 1 get notify method 1 get notify method 1 get notify method 1 get notify method 1 get notify method 1 get notify method 1 get notify method 1 get notify method 1 get notify method 1 get notify method 1 is out lock method 1 is end method 2 is end上例中,線程1執行method1先獲取對象鎖,然后判斷flag的值,如果flag>0,則wait等待,此時釋放鎖。因此線程2執行method2可以獲取對象鎖,并且每次在鎖內執行flag--,然后執行notify()通知其他線程,接著釋放鎖。線程1獲取notify信號后,先獲取對象鎖,然后沿著wait方法繼續向下執行。
wait()方法與notify()必須要與synchronized(resource)一起使用。也就是wait與notify針對已經獲取了resource鎖的線程進行操作,從語法角度來說就是Obj.wait(),Obj.notify必須在synchronized(Obj){...}語句塊內。從功能上來說wait()線程在獲取對象鎖后,主動釋放CPU控制權,主動釋放對象鎖,同時本線程休眠。直到有其它線程調用對象的notify()喚醒該線程,才能繼續獲取對象鎖,并繼續執行。相應的notify()就是對對象鎖的釋放操作。
【因此,我們可以發現,wait和notify方法均可釋放對象的鎖,但wait同時釋放CPU控制權,即它后面的代碼停止執行,線程進入阻塞狀態,而notify方法不立刻釋放CPU控制權,而是在相應的synchronized(){}語句塊執行結束,再自動釋放鎖。】
釋放鎖后,JVM會在等待resoure的線程中選取一線程,賦予其對象鎖,喚醒線程,繼續執行。這樣就提供了在線程間同步、喚醒的操作。Thread.sleep()與Object.wait()二者都可以暫停當前線程,釋放CPU控制權,主要的區別在于Object.wait()在釋放CPU同時,釋放了對象鎖的控制,而在同步塊中的Thread.sleep()方法并不釋放鎖,僅釋放CPU控制權。
轉載于:https://www.cnblogs.com/wuchaodzxx/p/5986765.html
總結
以上是生活随笔為你收集整理的sleep(),wait(),yield(),notify()的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据库一对一,一对多,多对多关系
- 下一篇: POJ2718【DFS】