在JAVA的學習中,不少人會把
sleep
和wait
搞混,認爲都是做線程的等待,下面主要介紹下這倆者是什麼,及瞭解它們之間的差異和相似之處。
一般差異
簡單來說,wait()
是一個用於線程同步
的實例方法。它可以在任何對象上調用,因爲它定義在java.lang.Object
上, 但只能從同步塊中調用
。它釋放對象上的鎖,以便另一個線程可以跳入並獲取鎖。
另一方面,Thread.sleep()
是可以從任何上下文調用的靜態方法。Thread.sleep()暫停當前線程
,不釋放任何鎖。
主要區別
sleep()
線程控制自身流程。wait()
用來線程間通信,使擁有該對象鎖的線程等待直到指定時間或notify()。wait()
會釋放鎖和監視器,sleep()
不釋放任何鎖或監視器等。wait()
用於線程間通信,而sleep()
用於在執行時引入暫停- 適用區域,
wait
只能放在同步語句
塊中才有意義。
注意事項
wait可以代替sleep嗎?
不可以,如果直接調用wait
會拋出java.lang.IllegalMonitorStateException
異常,原因是還沒有得到對象鎖
,所以無法釋放鎖。
如何獲取鎖?
- 執行對象的
synchronized
實例方法。 - 執行對象對應類的
synchronized
靜態方法。 - 執行對該對象加
synchronized
的同步代碼塊。
演示
Thread.sleep
static void method1() {
synchronized (LOCK) {
try {
System.out.println("[" + Thread.currentThread().getName() + "] begin sleep ...");
Thread.sleep(5_000);
System.out.println("[" + Thread.currentThread().getName() + "] end sleep ...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Stream.of("T1", "T2").forEach(name -> new Thread(DifferenceOfWaitAndSleep::method1, name).start());
}
運行此示例一共將一共耗時10S
,因T1線程
獲得鎖後會暫停執行,這時候LOCK
依舊在T1線程
中,然後纔會被T2線程
獲取
[T1] begin sleep ...
[T1] end sleep ...
[T2] begin sleep ...
[T2] end sleep ...
Object.wait
static void method2() {
synchronized (LOCK) {
try {
System.out.println("[" + Thread.currentThread().getName() + "] begin wait ...");
LOCK.wait();
System.out.println("[" + Thread.currentThread().getName() + "] end wait ...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Stream.of("T1", "T2").forEach(name -> new Thread(DifferenceOfWaitAndSleep::method2, name).start());
}
運行此示例會立即輸出T1/T2 begin wait ...
但永遠不會輸出T1/T2 end wait ...
,因爲沒有線程調用LOCK.notify/notifyAll
將它們喚醒
[T1] begin wait ...
[T2] begin wait ...
結論
調用:
wait(): 對象調用,當前線程必須在持有鎖的對象上進行同步。
sleep(): 線程調用,始終執行的當前線程
同步:
wait(): 同步多個線程同時訪問一個對象時
sleep(): 多個線程同步等待線程休眠
鎖:
wait(): 釋放鎖,其它線程有機會執行
sleep(): 持有鎖,固定時間後釋放或被打斷(interrupt)
喚醒條件:
wait(): 直到調用對象的 notify、notifyAll
sleep(): 直到至少時間到期或者調用interrupt()
使用:
sleep(): 用於時間同步
wait(): 用於多線程同步
- 說點什麼
- 個人QQ:1837307557
- battcn開源羣(適合新手):391619659
微信公衆號:battcn
(歡迎調戲)