1.概覽
? 在這篇簡單的文章中,我們將會看到標準的sleep()和wait()方法,并且理解他們的區(qū)別和相似性。
2.wait和sleep的一般區(qū)別
簡單點說,wait()方法是個實例方法,它主要用于線程同步。它可以被任何對象調(diào)用,因為這個方法是被定義在Object類里的。但是它只能從一個同步代碼塊中被調(diào)用。只有它釋放了對象上的鎖后,其他線程才能進入并獲取鎖。
另一方面,Thread.sleep()是一個靜態(tài)方法,它可以在任何環(huán)境中被調(diào)用。Thread.sleep() 會暫停當前線程并且不會釋放任何鎖。
這里有一個關(guān)于這倆個API的例子:
privatestaticObject LOCK = newObject();
privatestaticvoidsleepWaitExamples()
??throwsInterruptedException {
????Thread.sleep(1000);
????System.out.println(? "Thread '"+ Thread.currentThread().getName() +? "' is woken after sleeping for 1 second");
????synchronized(LOCK) {
????????LOCK.wait(1000);
????????System.out.println("Object '"+ LOCK + "' is woken after"+
??????????" waiting for 1 second");
????}
}
3.喚醒 Wait和Sleep
當我們使用sleep()方法時,線程會在指定的時間間隔內(nèi)啟動(get started),除非他被中斷了。
對于wait()方法來說,喚醒處理要更復雜一些。調(diào)用當前正在等待的監(jiān)視器的notify()或 notifyAll()方法可以喚醒該線程。
你可以使用notifyAll()方法喚醒所有處于等待狀態(tài)下的線程。和wait()方法類似,notify()和notifyAll()方法只能在一個同步上下文中被調(diào)用。
例如,這里有一個wait的例子:
synchronized(b) {
????while(b.sum == 0) {
????????System.out.println("Waiting for ThreadB to complete...");
????????b.wait();
????}
????System.out.println("ThreadB has completed. "+
??????"Sum from that thread is: "+ b.sum);
}
之后,下面會演示另一個線程是如何會喚醒該等待的線程----通過調(diào)用monitor對象上的notify()方法:
int sum;
@Override
public void run() {
? ? synchronized (this) {
? ? ? ? int i = 0;
? ? ? ? while (i < 100000) {
? ? ? ? ? ? sum += i;
? ? ? ? ? ? i++;
? ?}
? ? ? ? notify();
? ? }
}
運行這個例子將會產(chǎn)生下面的輸出:
Waiting for ThreadB to complete…
ThreadB has completed.?Sum?from that thread is: 704982704
4.總結(jié)
這篇文章是對wait和sleep()語法的一個入門。
? 通常來說,我們可以使用sleep()去控制一個線程的執(zhí)行時間,使用wait()方法去控制多線程同步,當然了,在理解完這些最基本的概念之后,還有好多東西需要我們?nèi)ヌ剿鳌?和往常一樣,你可以從這個地址處https://github.com/eugenp/tutorials/tree/master/core-java-concurrency/src/main/java/com/baeldung/concurrent/sleepwait去check案例代碼。