sleep(休眠) 和 wait(等待) 方法是 Java 多線程中經常使用的兩個方法,它們有什麼區別及一些該注意的地方有哪些呢?下面給你們一一分解。java
使用 sleep 方法可讓讓當前線程休眠,時間一到當前線程繼續往下執行,在任何地方都能使用,但須要捕獲 InterruptedException 異常。面試
try { Thread.sleep(3000L); } catch (InterruptedException e) { e.printStackTrace(); }
而使用 wait 方法則必須放在 synchronized 塊裏面,一樣須要捕獲 InterruptedException 異常,而且須要獲取對象的鎖。微信
synchronized (lock){ try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } }
並且 wait 還須要額外的方法 notify/ notifyAll 進行喚醒,它們一樣須要放在 synchronized 塊裏面,且獲取對象的鎖。。多線程
synchronized (lock) { // 隨機喚醒 lock.notify(); // 喚醒所有 lock.notifyAll(); }
固然也可使用帶時間的 wait(long millis) 方法,時間一到,無需其餘線程喚醒,也會從新競爭獲取對象的鎖繼續執行。架構
sleep 通常用於當前線程休眠,或者輪循暫停操做,wait 則多用於多線程之間的通訊。分佈式
sleep 是 Thread 類的靜態本地方法,wait 則是 Object 類的本地方法。線程
java.lang.Thread#sleep架構設計
public static native void sleep(long millis) throws InterruptedException;
java.lang.Object#wait設計
public final native void wait(long timeout) throws InterruptedException;
爲何要這樣設計呢?code
由於 sleep 是讓當前線程休眠,不涉及到對象類,也不須要得到對象的鎖,因此是線程類的方法。wait 是讓得到對象鎖的線程實現等待,前提是要楚得到對象的鎖,因此是類的方法。
Object lock = new Object(); synchronized (lock) { try { lock.wait(3000L); Thread.sleep(2000L); } catch (InterruptedException e) { e.printStackTrace(); } }
如上代碼所示,wait 能夠釋放當前線程對 lock 對象鎖的持有,而 sleep 則不會。
sleep 會讓出 CPU 執行時間且強制上下文切換,而 wait 則不必定,wait 後可能仍是有機會從新競爭到鎖繼續執行的。
@程序猿 大家還知作別的嗎?歡迎留言!
更多幹貨推薦
2.史上最強 Spring Boot & Cloud 教程整理
更多請掃描下方的二維碼關注咱們的微信公衆號,乾貨每日推送!