執行緒中常見的方法
start()
啟動一個新的執行緒,在新的執行緒中執行run()方法中的程式碼
start方法只是讓執行緒進入就緒狀態,不是馬上執行。需要等待CPU的時間片分給它
一個執行緒的 start 方法只能呼叫一次,如果多次呼叫會丟擲IllegalThreadStateException
run()
新執行緒啟動後會呼叫的方法,如果在構造 Thread 物件時傳遞了 Runnable,執行緒啟動後會呼叫 Runnable 中的 run 方法,否則預設不執行任何操作
如果同時傳遞 Runnable 和重寫 run 方法,那麼會執行的當然是重寫的 run 方法
join()
等待某個執行緒結束
如下程式碼:
主執行緒直接獲取a的值,得到的是0
如果我們想要讀取到t1修改a的值,那麼就需要使用join()
join內部是用wait方法實現的
join如果不帶時間,那就是一直等。如果帶了時間,那就是如果時間到了還沒執行緒還沒結束,那麼就繼續了,不等了
yield()
呼叫 yield 方法會排程執行其他同優先順序的執行緒。如果這時沒有其他同優先順序的執行緒,那麼不能保證讓當前執行緒暫停
yield 的作用只相當於提示,並不保證一定有效果,具體的實現依賴於作業系統的任務排程器
這個方法的主要作用在於測試和除錯
sleep()
這個方法很熟悉了,使執行緒暫停一段時間,如果持有鎖,那麼 sleep 時也不會釋放鎖
wait()
必須持有鎖才能呼叫此方法,否則會丟擲IllegalMonitorStateException
。作用在於當一個執行緒獲取鎖之後,發現當前不滿足執行條件,空等又浪費資源,所以使用 wait 方法釋放鎖,自己進入 Monito r中 waitset 中等待被 notify 和 notifyall 喚醒。釋放鎖之後,其他執行緒搶到鎖成為 owner ,沒搶到的繼續阻塞
wait 方法並不是 Thread 類中的方法,而是 Object 的方法
為什麼這些操作執行緒的方法要定義在 Object 類中呢?
簡單說:因為 synchronized 中的這把鎖可以是任意物件,所以任意物件都可以呼叫 wait() 和 notify() ;所以 wait 和 notify 屬於 Object 。
專業說:因為這些方法在操作同步執行緒時,都必須要標識它們操作執行緒的鎖,只有同一個鎖上的被等待執行緒,可以被同一個鎖上的 notify 喚醒,不可以對不同鎖中的執行緒進行喚醒
也就是說,等待和喚醒必須是同一個鎖。而鎖可以是任意物件,所以可以被任意物件呼叫的方法是定義在Object類中
sleep 和 wait 的區別
- sleep 是 Thread 方法,而 wait 是 Object 的方法
- sleep 不需要強制和 synchronized 配合使用,但 wait 需要和 synchronized 一起用,也就是上面說的一定要獲取到鎖
- sleep 如果獲取到了鎖,不會釋放,但是wait會釋放鎖
interrupt()
打斷執行緒
如果被打斷執行緒正在 sleep,wait,join 會導致被打斷的執行緒丟擲InterruptedException,並清除打斷標記
如果打斷正在執行的執行緒,則會設定打斷標記
isInterrupted:判斷是否被打斷,不會清除打斷標記
interrupted:判斷是否被打斷,會清除打斷標記