1. 程式人生 > >執行緒的幾種狀態以及sleep,wait,yield,join的區別

執行緒的幾種狀態以及sleep,wait,yield,join的區別

今天第一次寫部落格,因個人能力有限,不到位的地方請大家多多包涵 1.執行緒通常有五種狀態,建立,就緒,執行、阻塞和死亡狀態。 2.阻塞的情況又分為三種: (1)、等待阻塞:執行的執行緒執行wait()方法,該執行緒會釋放佔用的所有資源,JVM會把該執行緒放入“等待池”中。進入這個狀態後,是不能自動喚醒的,必須依靠其他執行緒呼叫notify()或notifyAll()方法才能被喚醒, wait是object類的方法 (2)、同步阻塞:執行的執行緒在獲取物件的同步鎖時,若該同步鎖被別的執行緒佔用,則JVM會把該執行緒放入“鎖池”中。 (3)、其他阻塞:執行的執行緒執行sleep()或join()方法,或者發出了I/O請求時,JVM會把該執行緒置為阻塞狀態。當sleep()狀態超時、join()等待執行緒終止或者超時、或者I/O處理完畢時,執行緒重新轉入就緒狀態。 sleep是Thread類的方法
1.新建狀態(New):新建立了一個執行緒物件。 2.就緒狀態(Runnable):執行緒物件建立後,其他執行緒呼叫了該物件的start()方法。該狀態的執行緒位於可執行執行緒池中,變得可執行,等待獲取CPU的使用權。 3. 執行狀態(Running):就緒狀態的執行緒獲取了CPU,執行程式程式碼。 4.阻塞狀態(Blocked):阻塞狀態是執行緒因為某種原因放棄CPU使用權,暫時停止執行。直到執行緒進入就緒狀態,才有機會轉到執行狀態。 阻塞的情況分三種: (一)、等待阻塞:執行的執行緒執行wait()方法,JVM會把該執行緒放入等待池中。 (二)、同步阻塞:執行的執行緒在獲取物件的同步鎖時,若該同步鎖被別的執行緒佔用,則JVM會把該執行緒放入鎖池中。( 三)、其他阻塞:執行的執行緒執行sleep()或join()方法,或者發出了I/O請求時,JVM會把該執行緒置為阻塞狀態。當sleep()狀態超時、join()等待執行緒終止或者超時、或者I/O處理完畢時,執行緒重新轉入就緒狀態。 5.死亡狀態(Dead):執行緒執行完了或者因異常退出了run()方法,該執行緒結束生命週期。
Java中sleep,wait,yield,join的區別
1.sleep()方法 在指定時間內讓當前正在執行的執行緒暫停執行,但不會釋放“鎖標誌”。不推薦使用。 sleep()使當前執行緒進入阻塞狀態,在指定時間內不會執行。 2.wait()方法 在其他執行緒呼叫物件的notify或notifyAll方法前,導致當前執行緒等待。執行緒會釋放掉它所佔有的“鎖標誌”,從而使別的執行緒有機會搶佔該鎖。 當前執行緒必須擁有當前物件鎖。如果當前執行緒不是此鎖的擁有者,會丟擲IllegalMonitorStateException異常。
喚醒當前物件鎖的等待執行緒使用notify或notifyAll方法,也必須擁有相同的物件鎖,否則也會丟擲IllegalMonitorStateException異常。 waite()和notify()必須在synchronized函式或synchronized block中進行呼叫。如果在non-synchronized函式或non-synchronized block中進行呼叫,雖然能編譯通過,但在執行時會發生IllegalMonitorStateException的異常。 3.yield方法 暫停當前正在執行的執行緒物件。 yield()只是使當前執行緒重新回到可執行狀態,所以執行yield()的執行緒有可能在進入到可執行狀態後馬上又被執行。 yield()只能使同優先順序或更高優先順序的執行緒有執行的機會。  呼叫yield方法並不會讓執行緒進入阻塞狀態,而是讓執行緒重回就緒狀態,它只需要等待重新獲取CPU執行時間,這一點是和sleep方法不一樣的。 4.join方法 等待該執行緒終止。 等待呼叫join方法的執行緒結束,再繼續執行。如:t.join();//主要用於等待t執行緒執行結束,若無此句,main則會執行完畢,導致結果不可預測。 在很多情況下,主執行緒建立並啟動了執行緒,如果子執行緒中藥進行大量耗時運算,主執行緒往往將早於子執行緒結束之前結束。這時,如果主執行緒想等待子執行緒執行完成之後再結束,比如子執行緒處理一個數據,主執行緒要取得這個資料中的值,就要用到join()方法了。方法join()的作用是等待執行緒物件銷燬。
① sleep()方法給其他執行緒執行機會時不考慮執行緒的優先順序,因此會給低優先順序的執行緒以執行的機會;yield()方法只會給相同優先順序或更高優先順序的執行緒以執行的機會;
join的意思是會等到呼叫改join方法的執行緒執行完畢之後才會執行其他執行緒,舉例說明: public static void main(String[] args) throws InterruptedException { //開啟一個執行緒 Thread thread = new Thread(new Runnable() { @Override public void run() { System.out.println("我是新開副執行緒的執行"); //這個方法會先讓副執行緒沉睡1秒之後在執行,但是期間不會影響主執行緒的執行 Thread.sleep(1000L); } }); thread.start();//啟動執行緒 //這個方法會等副執行緒執行完成之後才會接下來執行主執行緒,會影響主執行緒的執行 thread.join();
System.out.println("我是主執行緒的執行"); }