這個是面試經常被問到的問題,多執行緒的話首先要對執行緒的狀態有個清晰的認識才可以;這裡做個簡單的總結;
1.新建狀態(new):新建立乙個執行緒物件的初始狀態;也就是通過new關鍵字建立乙個執行緒物件,;,但並沒有呼叫start方法時候的狀態;
thread t = new thread ( tt)
2.就緒狀態(runnable):執行緒有資格執行,但排程程式還沒有把它選為執行執行緒時的狀態,此時,執行緒具備執行的條件,一旦被選中,馬上就可以執行。執行緒建立後,呼叫了start方法,執行緒不處於執行狀態;該狀態下,等待作業系統的排程,獲取cpu使用權之後就可以執行執行緒**;
3.執行狀態:從就緒狀態池中被選擇為當前執行的執行緒的狀態;
4.阻塞狀態(blocked):執行緒在執行的過程中,遇到被synchronized關鍵字保護的**,等待獲得被保護物件的鎖,此時執行緒會停止執行;這個地方要注意,只有synchronized鎖才會讓執行緒進入到blocked狀態,等待利用cas實現的鎖(reentrantlock),執行緒仍然處於runnable狀態。
5.等待狀態(watting):執行緒處於等待狀態只有一種情況,就是呼叫wait方法,如下所示
public static void timedwaiting() catch (interruptedexception e)
}}
6.死亡狀態(dead):執行緒執行完了或者異常退出run方法,執行緒結束生命週期;
其他的一些說明:
1> wait和sleep方法的區別
wait方法和sleep方法都可以使執行緒處於等待狀態,區別是,wait方法會釋放物件的鎖,而sleep方法則不會;
兩個方法分別來自不同的類,wait是object物件的方法,而sleep是執行緒thread類的方法;
wait,notify和notifyall只能用在同步控制方法或者同步控制塊中,而sleep方法可以在任何地方使用;
sleep方法屬於thread類中的方法,表示讓乙個執行緒進入休眠狀態,等待一定時間之後,自動醒來進入到可執行狀態,只對當前執行緒有效,而wait屬於object方法,一旦乙個物件呼叫了wait方法,必須採用notify和notifyall方法喚醒該程序;
如果執行緒a希望立即結束執行緒b,則可以對執行緒b對應的thread例項呼叫interrupt方法,如果此刻執行緒b處於wait/sleep/join,則執行緒b會立刻丟擲interruptedexception error;
wait()和notify()因為會對物件的「鎖標誌」進行操作,所以它們必須在synchronized函式或synchronized block中進行呼叫。如果在non-synchronized函式或non-synchronizedblock中進行呼叫,雖然能編譯通過,但在執行時會發生illegalmonitorstateexception的異常。
2>join方法
join方法用於在某乙個執行緒執行的過程中呼叫另乙個執行緒,等到被呼叫的執行緒執行結束後,再繼續執行當前執行緒,理解就是講執行緒從並行變成序列;舉個簡單的例子說明
public class jointest
}class threadjointest extends thread
@override
public void run()
}}
上面程式結果是先列印完小明執行緒,在列印小東線程;join方法也可以傳遞乙個引數
threadjointest t1 = new threadjointest("小明");
threadjointest t2 = new threadjointest("小東");
t1.start();
/**join方法可以傳遞引數,join(10)表示main執行緒會等待t1執行緒10毫秒,10毫秒過去後,
* main執行緒和t1執行緒之間執行順序由序列執行變為普通的並行執行
*/t1.join(10);
t2.start();
所以,join方法中如果傳入引數,則表示這樣的意思:如果a執行緒中掉用b執行緒的join(10),則表示a執行緒會等待b執行緒執行10毫秒,10毫秒過後,a、b執行緒並行執行。需要注意的是,jdk規定,join(0)的意思不是a執行緒等待b執行緒0秒,而是a執行緒等待b執行緒無限時間,直到b執行緒執行完畢,即join(0)等價於join()。
注意:join必須用在start方法後面,否則沒有任何作用,因為執行緒還沒有開始,呼叫join方法將毫無意義;
join方法的實現原理:其實還是呼叫執行緒的wait方法來達到同步的目的。例如a執行緒中呼叫了b執行緒的join方法,則相當於在a執行緒中呼叫了b執行緒的wait方法,當b執行緒執行完(或者到達等待時間),b執行緒會自動呼叫自身的notifyall方法喚醒a執行緒,從而達到同步的目的。
3>多執行緒wait和notify判斷條件時,一定使用while,而不是if,舉個例子:如果有兩個生產者a和b,乙個消費者c。當儲存空間滿了之後,生產者a和b都被wait,進入等待喚醒佇列。當消費者c取走了乙個資料後,如果呼叫了notifyall(),注意,此處是呼叫notifyall(),則生產者執行緒a和b都將被喚醒,如果此時a和b中的wait不在while迴圈中而是在if中,則a和b就不會再次判斷是否符合執行條件,都將直接執行wait()之後的程式,那麼如果a放入了乙個資料至儲存空間,則此時儲存空間已經滿了;但是b還是會繼續往儲存空間裡放資料,錯誤便產生了;
執行緒的幾種狀態
執行緒的幾種狀態及狀態之間的轉化 新建狀態 建立乙個新的執行緒 此時執行緒未啟動 就緒狀態 乙個新建的執行緒並不會自動開始執行,要執行執行緒,必須呼叫執行緒的start 方法,當執行緒物件呼叫start 方法啟動了執行緒,start 方法建立執行緒執行的系統資源,並排程執行緒執行run 方法,當st...
執行緒 執行緒的幾種狀態轉換。
執行緒在一定條件下,狀態會發生變化。執行緒一共有以下幾種狀態。1.新建狀態 new 新建立了乙個執行緒物件。2.就緒狀態 runnable 執行緒物件建立後,在其他地方呼叫了該執行緒的start 方法,該執行緒準備好所有執行前的資源,然後位於可執行執行緒池中,變得可執行,等待cpu的執行權。3.執行...
執行緒的幾種可用狀態
1.新建 new 新建立了乙個執行緒物件。2.可執行 runnable 執行緒物件建立後,其他執行緒 比如 main 執行緒 呼叫了該物件 的 start 方法。該狀態的執行緒位於可執行執行緒池中,等待被執行緒排程選中,獲 取 cpu 的使用權 3.執行 running 可執行狀態 runnable...