堅持每天寫博文,積累下開發中的點點滴滴
Java中的多線程是一種搶佔式的機制而不是分時機制。
線程主要有以下幾種狀態:
就緒(Runnable):線程準備運行,不一定立馬就能開始執行。
運行中(Running):進程正在執行線程的代碼。
等待中(Waiting):線程處於阻塞的狀態,等待外部的處理結束。
睡眠中(Sleeping):線程被強制睡眠。
I/O阻塞(Blocked on I/O):等待I/O操作完成。
同步阻塞(Blocked on Synchronization):等待獲取鎖。
死亡(Dead):線程完成了執行。
- 搶佔式機制
指的是有多個線程處於可運行狀態,但是隻有一個線程在運行;每個對象都有一個機鎖來控制同步訪問。Synchronized關鍵字可以和對象的機鎖交互,來實現線程的同步。
由於sleep()方法是Thread類的方法,因此它不能改變對象的機鎖。所以當在一個Synchronized方法中調用sleep()時,線程雖然休眠了,但是對象的機鎖沒有被釋放,其他線程仍然無法訪問這個對象。
而wait()方法則會在線程休眠的同時釋放掉機鎖,其他線程可以訪問該對象。
一個線程結束的標誌是:run()方法結束。
Wait()方法和notify()方法:當一個線程執行到wait()方法時(線程休眠且釋放機鎖),它就進入到一個和該對象相關的等待池中,同時失去了對象的機鎖。當它被一個notify()方法喚醒時,等待池中的線程就被放到了鎖池中。該線程從鎖池中獲得機鎖,然後回到wait()前的中斷現場。
- Yield()方法
是停止當前線程,讓同等優先權的線程運行。如果沒有同等優先權的線程,那麼Yield()方法將不會起作用。
- join()方法
使當前線程停下來等待,直至另一個調用join方法的線程終止。
值得注意的是:線程的在被激活後不一定馬上就運行,而是進入到可運行線程的隊列中。
- wait和sleep方法的區別
- sleep方法只讓出了CPU,而並不會釋放同步資源鎖
wait()方法則是指當前線程讓自己暫時退讓出同步資源鎖,以便其他正在等待該資源的線程得到該資源進而運行,只有調用了notify()方法,之前調用wait()的線程纔會解除wait狀態 - sleep()方法可以在任何地方使用;wait()方法則只能在同步方法或同步塊中使用;
- sleep()是線程線程類(Thread)的方法,
wait()是Object的方法 - sleep必須捕獲異常,而wait,notify和notifyAll不需要捕獲異常
- sleep方法只讓出了CPU,而並不會釋放同步資源鎖