鎖池和等待池
notify和notifyall的區別
常見異常
執行緒的五個狀態:新建狀態、就緒狀態、執行狀態、阻塞狀態、死亡狀態
三種阻塞狀態:等待阻塞、同步阻塞、其他阻塞
1. 等待阻塞:執行wait方法
2. 同步阻塞:synchronizedd同步鎖被其他執行緒占用,獲取失敗
3. 其他阻塞:執行join方法、sleep方法
thread.
yield()
; 執行緒物件.
join()
;
yeild作用:禮讓其他執行緒,當前執行緒從執行狀態回到就緒狀態,並放棄當前cpu的資源,使同優先順序或者高優先順序的執行緒得到執行機會,但並不一定就會執行其他執行緒,當前放棄資源的執行緒也有可能立即獲得執行機會
join的作用:當前執行緒等待呼叫join方法的執行緒執行完成後,再執行當前執行緒。【當前執行緒中,通過其他執行緒物件呼叫join方法,當前執行緒進入阻塞狀態】
(1)sleep是thread類中的靜態方法,但wait是object類中的普通方法,所有類中都繼承了wait方法,即任意物件都可以呼叫wait方法,但實際只有這個物件作為同步鎖時才能呼叫
thread.
sleep(10
);//wait的用法,必須和synchronized配合使用
synchronized
(同步鎖物件)
(2)sleep是執行緒由執行狀態變為休眠阻塞狀態,不會釋放鎖,而wait是執行緒由執行狀態變為等待阻塞狀態,不僅會釋放鎖,而且會加入到等待佇列中
注意: 執行緒只能從就緒狀態進入執行狀態,因此阻塞狀態要先進入就緒狀態,才能再次進入執行狀態
(3)sleep方法不依賴於同步鎖物件(synchronized的監視器物件),但是wait方法需要依賴同步鎖物件,呼叫wait方法的前提是當前執行緒使用了同步鎖(即**要在synchronized中)。
(4)sleep不需要喚醒,而wait需要被notify或notifyall喚醒
相同點:sleep和wait都能通過interrupt方法打斷
thread.sleep(0) 並非是真的要執行緒掛起0毫秒,意義在於這次呼叫thread.sleep(0)的當前執行緒確實的被凍結了一下,讓其他執行緒有機會優先執行。thread.sleep(0) 是你的執行緒暫時放棄cpu,也就是釋放一些未用的時間片給其他執行緒或程序使用,就相當於乙個讓位動作。
thread.sleep(1000) 意思是在未來的1000毫秒內本執行緒不參與cpu競爭,1000毫秒過去之後,這時候也許另外乙個執行緒正在使用cpu,那麼這時候作業系統是不會重新分配cpu的,直到那個執行緒掛起或結束,即使這個時候恰巧輪到作業系統進行cpu 分配,那麼當前執行緒也不一定就是總優先順序最高的那個,cpu還是可能被其他執行緒搶占去。另外值得一提的是thread.sleep(0)的作用,就是觸發作業系統立刻重新進行一次cpu競爭,競爭的結果也許是當前執行緒仍然獲得cpu控制權,也許會換成別的執行緒獲得cpu控制權。
wait(1000)表示將鎖釋放1000毫秒,到時間後如果鎖沒有被其他執行緒占用,則再次得到鎖,然後wait方法結束,執行後面的**,如果鎖被其他執行緒占用,則等待其他執行緒釋放鎖。注意,設定了超時時間的wait方法一旦過了超時時間,並不需要其他執行緒執行notify也能自動解除阻塞,但是如果沒設定超時時間的wait方法必須等待其他執行緒執行notify。
注意:wait() 需要被try catch包圍,以便發生異常中斷也可以使wait等待的執行緒喚醒。
鎖池:假設執行緒a已經擁有了同步鎖,而其它的執行緒想要呼叫這個物件的某個synchronized方法(或者synchronized塊),由於這些執行緒在進入物件的synchronized方法之前必須先獲得該物件的鎖的擁有權,但是該物件的鎖目前正被執行緒a擁有,所以這些執行緒就進入了該物件的鎖池中。
等待池:假設乙個執行緒a呼叫了某個同步鎖的wait()方法,執行緒a就會釋放同步鎖,進入到了該同步鎖的等待池中
如果執行緒呼叫了某個同步鎖的wait()方法,那麼執行緒便會處於該同步鎖的等待池中,等待池中的執行緒不會去競爭同步鎖,如果要想競爭同步鎖,就必須通過notify和notifyall方法喚醒。
notify方法:如果有多個執行緒在等待池中等待,這個方法只會隨機喚醒乙個wait 執行緒,該執行緒會由等待池進入鎖池,然後與鎖池中其他執行緒一起競爭同步鎖。具體喚醒哪個執行緒取決於執行緒排程器
notifyall方法:如果有多個執行緒在等待池中等待,notifyall方法將喚醒該同步鎖的所有wait執行緒,被喚醒的的執行緒都會進入該同步鎖的鎖池中,然後與鎖池中其他執行緒一起競爭同步鎖。
優先順序高的執行緒競爭到物件鎖的概率大,假若某執行緒沒有競爭到該物件鎖,它還會留在鎖池中,唯有執行緒再次呼叫 wait()方法,它才會重新回到等待池中,而競爭到物件鎖的執行緒則繼續往下執行,直到執行完了 synchronized **塊,它會釋放掉該物件鎖,這時鎖池中的執行緒會繼續競爭該物件鎖。
異常原因:當前的執行緒的物件監視器【同步鎖】不是該物件【新建的objectd物件】,這個demo中沒有使用synchronize來進行同步,因此沒有指定同步鎖,因此會拋異常。
解決辦法:synchronized關鍵字指定執行緒的同步鎖是哪個物件,就需要用該物件呼叫notify()、notifyall(),wait()、wait(long)、 wait(long, int)等方法,否則其他物件來呼叫這些方法就會丟擲上述異常
執行緒的五種狀態
1.建立狀態,執行緒剛剛建立還未呼叫start方法。2.就緒狀態,呼叫start方法,還未搶到cpu執行權。3.執行狀態,搶到cpu執行權,執行run方法。4.阻塞狀態,包含sleep和wait 1 sleep使先執行緒處於睡眠狀態,期間讓出cpu使用權,不釋放資源。2 wait是執行緒處於等待狀態...
執行緒的五種狀態
1 新建狀態 new 當執行緒物件對建立後,即進入了新建狀態,如 thread t new mythread 2 就緒狀態 runnable 當呼叫執行緒物件的start 方法 t.start 執行緒即進入就緒狀態。處於就緒狀態的執行緒,只是說明此執行緒已經做好了準備,隨時等待cpu排程執行,並不是...
Java執行緒的五種狀態
new 乙個執行緒被建立但是沒有呼叫start方法 runnable 可執行的執行緒,即執行緒執行了start方法之後,正在執行或者正在等待某個資源 blocked 執行緒等待鎖來進入同步方法或 塊。waiting 乙個執行緒正在等待另乙個執行緒來喚醒,可能是由於呼叫了以下方法 timed wait...