<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
wait()和notify()是Object類的方法,用於執行緒的等待與喚醒,必須搭配synchronized 鎖來使用。
多執行緒並行的場景下,有時需要某些執行緒先執行,這些執行緒執行結束後其他執行緒再繼續執行。
比如: 一個長跑比賽,裁判員要等跑步運動員衝線了才能宣判比賽結束,那裁判員執行緒就得等待所有的運動員執行緒執行結束後,再喚醒這個裁判執行緒。
wait 做的事情:
wait 要搭配 synchronized 來使用. 脫離 synchronized 使用 wait 會直接丟擲異常.
wait 結束等待的條件:
注意事項:
等待方法:
1.痴漢方法,死等,執行緒進入阻塞態(WAITING)直到有其他執行緒呼叫notify方法喚醒
2.等待一段時間,若在該時間內執行緒被喚醒,則繼續執行,若超過相應時間還沒有其他執行緒喚醒此執行緒,此執行緒不再等待,恢復執行。
呼叫wait方法之後:
notify 方法是喚醒等待的執行緒.
注意事項:
對於wait和notify方法,其實有一個阻塞佇列也有一個等待佇列。
舉個栗子:
現有如下定義的等待執行緒任務
private static class WaitTask implements Runnable { private Object lock; public WaitTask(Object lock) { this.lock = lock; } @Override public void run() { synchronized (lock) { System.out.println(Thread.currentThread().getName() + "準備進入等待狀態"); // 此執行緒在等待lock物件的notify方法喚醒 try { lock.wait(); Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } System.out.println(Thread.currentThread().getName() + "等待結束,本執行緒繼續執行"); } } }
然後建立三個等待執行緒:
由於同一時間只有一個執行緒(隨機排程)能獲取到synchronized鎖,所以會有兩個執行緒沒競爭到鎖,從而進入了阻塞佇列。
這裡假如t2先競爭到了鎖,所以先會阻塞t1和t3:
又由於呼叫wait方法會釋放鎖,呼叫wait方法的執行緒t2就會進入等待佇列,直到被notify喚醒或者超時自動喚醒。
然後此時lock物件已經被釋放了,所以t1和t3 又可以去競爭這個鎖了,就從阻塞佇列裡面競爭鎖。
這裡假如t3 競爭到了鎖,阻塞佇列只剩下t1:
然後t3執行到了wait方法,釋放鎖,然後進入等待佇列:
然後重複這些操作~~,最後t1,t2,t3 都進入了等待佇列中,等待notify執行緒喚醒(這裡假設notify要放在這些執行緒start後的好幾秒後,因為notify執行緒也是和這些執行緒並行執行的,所以等待佇列中的執行緒隨時可能被喚醒)
重點來了:
在等待佇列中的執行緒,被notify喚醒之後,會直接回到阻塞佇列去競爭鎖!!!而不是直接喚醒~
舉個栗子:
拿notifyAll()來舉例,假如此時等待佇列中有三個執行緒t1,t2,t3,那麼呼叫notifyAll()會直接把它們三個直接從等待佇列中進入到阻塞佇列中:
然後再去競爭這個鎖,去執行wait之後的程式碼~~
private static class WaitTask implements Runnable { private Object lock; public WaitTask(Object lock) { this.lock = lock; } @Override public void run() { synchronized (lock) { System.out.println(Thread.currentThread().getName() + "準備進入等待狀態"); // 此執行緒在等待lock物件的notify方法喚醒 try { lock.wait(); Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } System.out.println(Thread.currentThread().getName() + "等待結束,本執行緒繼續執行"); } } } private static class NotifyTask implements Runnable { private Object lock; public NotifyTask(Object lock) { this.lock = lock; } @Override public void run() { synchronized (lock) { System.out.println("準備喚醒"); // 喚醒所有執行緒(隨機) lock.notifyAll(); System.out.println("喚醒結束"); } } } public static void main(String[] args) throws InterruptedException { Object lock = new Object(); Object lock2 = new Object(); // 建立三個等待執行緒 Thread t1 = new Thread(new WaitTask(lock),"t1"); Thread t2 = new Thread(new WaitTask(lock),"t2"); Thread t3 = new Thread(new WaitTask(lock),"t3"); // 建立一個喚醒執行緒 Thread notify = new Thread(new NotifyTask(lock2),"notify執行緒"); t1.start(); t2.start(); t3.start(); ; Thread.sleep(100); notify.start(); // 當前正在執行的執行緒數 Thread.sleep(2000); System.out.println(Thread.activeCount() - 1); }
六、wait和sleep方法的區別(面試題):
以上就是多執行緒場景下wait和notify方法的詳解和注意事項了,更多相關多執行緒wait()和notify()方法內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45