我們先來介紹下鎖定池與等待池的概念。
首先來看下鎖定池的概念
所有需要競爭同步鎖定的執行緒都會放在鎖定池當中,例如目前物件的鎖定已經被其中一個執行緒得到,則其它執行緒需要在這個鎖池進行等待,當前面的執行緒釋放同步鎖侯鎖池中的執行緒去競爭同步鎖,當某個執行緒得到後會進入就緒佇列進行等待cpu資源分配。
接著來看看等待池的概念
當我們呼叫wait() 方法後,執行緒會放到等待池中,等待池的執行緒是不會去競爭同步鎖定。只有呼叫了notify() 或notifyAll() 後等待池的線程才會開始去競爭鎖,notify() 是隨機從等待池選出一個線程放到鎖池,而notifyAll() 是將等待池的所有線程放到鎖池當中。
sleep 是 Thread 類別的靜態本機方法,wait 則是Object的本機方法。
sleep 方法不會釋放lock,但wait 會釋放,而且會加入到等待佇列。
sleep就是把cpu的执行资格和执行权释放出去,不再运行此线程,当定时事件结束再取回cpu资源,参与cpu的调度,获取到cpu资源后就可以继续运行了,而如果sleep时该线程有锁,那么sleep不会释放这个锁,而是把锁带着进入了冻结状态,也就是说其它需要这个锁的线程根本不可能获取到这个锁。也就是说无法执行程序,如果在睡眠期间其它线程调用了这个线程的interrupt方法,那么这个线程也会抛出interruptexception异常返回,这点和wait是一样的。
sleep方法不依賴同步器synchronized,但wait需要依賴synchronized關鍵字。
sleep不需要被喚醒(休眠之後退出阻塞),但wait需要(不指定時間需要被別人中斷)。
sleep一般用於目前執行緒休眠,或輪詢暫停操作,wait則多用於多執行緒之間的通訊。
sleep會讓出CPU執行時間且強制上下文切換,而wait則不一定,wait後可能還是有機會重新競爭到鎖定繼續執行的。
yield() 執行後執行緒直接進入就緒狀態,馬上釋放了cpu的執行權,但是依然保留了cpu的執行資格,所以由可能cpu下次進行執行緒調度還會讓這個線程獲取到執行權繼續執行。
(學習影片分享:java影片教學)
join() 執行後執行緒進入阻塞狀態,例如在執行緒B中呼叫執行緒A的join() ,那線程B會進入到阻塞隊列,指導線程A結束或中斷線程。
public static void main(String[] args) throws InterruptedException { Thread t1=new Thread(()->{ try { Thread.sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("休眠sleep线程"); }); t1.start(); t1.join(); System.out.println("线程执行完成"); }
原文連結:https://blog.csdn.net/lxn1023143182/article/details/114134498
相關推薦:java訪談問題及答案
以上是面試官:請你說sleep()、wait()、join()和yield()的差別的詳細內容。更多資訊請關注PHP中文網其他相關文章!