您好,登錄后才能下訂單哦!
本篇內容主要講解“Java中sleep和wait方法有什么區別”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Java中sleep和wait方法有什么區別”吧!
根本區別:sleep是Thread類中的方法,不會馬上進入運行狀態,wait是Object類中的方法,一旦一個對象調用了wait方法,必須要采用notify()和notifyAll()方法喚醒該進程
釋放同步鎖:sleep會釋放cpu,但是sleep不會釋放同步鎖的資源,wait會釋放同步鎖資源
使用范圍: sleep可以在任何地方使用,但wait只能在synchronized的同步方法或是代碼塊中使用
異常處理: sleep需要捕獲異常,而wait不需要捕獲異常
使當前執行代碼的線程進行等待. (把線程放到等待隊列中)
釋放當前的鎖
滿足一定條件時被喚醒, 重新嘗試獲取這個鎖.
wait 要搭配 synchronized 來使用,脫離 synchronized 使用 wait 會直接拋出異常.
wait方法
/** * wait的使用 */ public class WaitDemo1 { public static void main(String[] args) { Object lock = new Object(); Thread t1 = new Thread(() -> { System.out.println("線程1開始執行"); try { synchronized (lock) { System.out.println("線程1調用wait方法...."); // 無限期的等待狀態 lock.wait(); } } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("線程1執行完成"); }, "線程1"); t1.start(); } }
有參wait線程和無參wait線程
/** * 有參wait線程和無參wait線程 */ public class WaitDemo2 { public static void main(String[] args) { Object lock1 = new Object(); Object lock2 = new Object(); Thread t1 = new Thread(()->{ System.out.println("線程1開始執行"); synchronized (lock1){ try { lock1.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("線程1執行完成"); } },"無參wait線程"); t1.start(); Thread t2 = new Thread(()->{ System.out.println("線程2開始執行"); synchronized (lock2){ try { lock2.wait(60*60*1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("線程2執行完成"); } },"有參wait線程"); t2.start(); } }
①其他線程調用該對象的 notify 方法.
②wait 等待時間超時 (wait 方法提供一個帶有 timeout 參數的版本, 來指定等待時間).
③其他線程調用該等待線程的 interrupted 方法, 導致 wait 拋出 InterruptedException 異常
notify 方法只是喚醒某一個等待的線程
方法notify()也要在同步方法或同步塊中調用,該方法是用來通知那些可能等待該對象的對象鎖的其它線程
如果有多個線程等待,隨機挑選一個wait狀態的線程
在notify()方法后,當前線程不會馬上釋放該對象鎖,要等到執行notify()方法的線程將程序執行完,也就是退出同步代碼塊之后才會釋放對象鎖
notify方法的使用
/** * wait的使用, 如果有多個線程等待,隨機挑選一個wait狀態的線程 */ public class WaitNotifyDemo { public static void main(String[] args) { Object lock1 = new Object(); Object lock2 = new Object(); Thread t1 = new Thread(()->{ System.out.println("線程1開始執行"); try { synchronized (lock1) { System.out.println("線程1調用wait方法"); lock1.wait(); } } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("線程1執行完成"); },"線程1"); Thread t2 = new Thread(()->{ System.out.println("線程2開始執行"); try { synchronized (lock1) { System.out.println("線程2調用wait方法"); lock1.wait(); } } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("線程2執行完成"); },"線程2"); t1.start(); t2.start(); // 喚醒 lock1 對象上休眠的線程的(隨機喚醒一個) Thread t3 = new Thread(()->{ try { Thread.sleep(1500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("線程3開始執行"); synchronized (lock1){ //發出喚醒通知 System.out.println("執行了喚醒"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } },"線程3"); t3.start(); } }
notifyAll方法可以一次喚醒所有的等待線程
notifyAll方法的使用
/** * notifyAll-喚醒所有線程 */ public class WaitNotifyAll { public static void main(String[] args) { Object lock = new Object(); new Thread(() -> { System.out.println("線程1:開始執行"); synchronized (lock) { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("線程1:執行完成"); } }, "無參wait線程").start(); new Thread(() -> { synchronized (lock) { System.out.println("線程2:開始執行 |" + LocalDateTime.now()); try { lock.wait(60 * 60 * 60 * 1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("線程2:執行完成 | " + LocalDateTime.now()); } }, "有參wait線程").start(); new Thread(() -> { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (lock) { System.out.println("喚醒所有線程"); lock.notifyAll(); } }).start(); } }
notify和notifyAll方法的區別
當你調用notify時,只有一個等待線程會被喚醒而且它不能保證哪個線程會被喚醒,這取決于線程調度器。
調用notifyAll方法,那么等待該鎖的所有線程都會被喚醒,但是在執行剩余的代碼之前,所有被喚醒的線程都將爭奪鎖定,這就是為什么在循環上調用wait,因為如果多個線程被喚醒,那么線程是將獲得鎖定將首先執行,它可能會重置等待條件,這將迫使后續線程等待。
因此,notify和notifyAll之間的關鍵區別在于notify()只會喚醒一個線程,而notifyAll方法將喚醒所有線程。
到此,相信大家對“Java中sleep和wait方法有什么區別”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。