1.當線程繼承Thread或者實現了Runnable創建了線程對象后,當new線程對象過后線程就進入了初始的狀態。
2.當線程對象調用了start()方法的時候,線程啟動進入可運行的狀態。
3.線程進入可運行狀態后,如果邏輯完成那么線程將會終結,如果沒有執行完畢中間JVM分配時間片用完,將進入可運行狀態,一旦線程被JVM選中則立即執行。
4.運行狀態的情況比較復雜
第一:線程如果執行run() main()方法結束后,完成邏輯,線程就進入Terminated
第二:當線程調用sleep()或者join()方法就會進入Blocked狀態,但是要注意的是阻塞的線程是不釋放當前所占有的系統資源,當sleep()結束或者join()等待其他線程來到,當前線程則進入Runnable狀態等待JVM分配資源。
第三:當線程進入Runnable狀態,但是還沒有開始運行的時候,此時發現需要的資源處于同步狀態synchronized,這個時候線程將會進入Time waiting,JVM會使用隊列對這些線程進行控制,既先進行Time waiting的線程會先得到JVM資源進行執行進入Waiting
第四:如果處于Runnable的線程調用yield()讓出JVM資源,那么就會進入New狀態和其他New狀態線程進行競爭重新進入Runnable
第五:如果當前線程調用wait()方法,則當前線程進入Time waiting但是這個時候當前線程會釋放所占有的JVM資源,進入這個狀態過后是不能自動喚醒的,必須調用notify()或者notifyAll()方法,線程進入Waiting。
1.首先sleep()是Thread類的方法靜態方法,需要通過Thread類調用,Thread.sleep()。而wait()和notify()是Object類中的實例方法,因為java所有類都繼承于object類,所有類中都可以使用。
2.wait(),和notify()必須用在synchronized代碼塊中調用,否則會拋出異常(因為wait()需要釋放對象鎖,如果不在synchronized代碼塊中不能保證擁有對象鎖)。
3.當在synchronized代碼塊中使用sleep(),線程會被掛起,但不會釋放對象鎖,所以如果有其他線程等待執行該synchronized代碼塊,一直會被阻塞,等待該線程被喚醒釋放對象鎖。
4.當在synchronized代碼塊中使用wait(),線程會被掛起,需要notify()喚醒,但該線程會釋放對象鎖,所以其他線程可以執行該synchronized代碼塊。