Java中wait sleep await 區別於聯系


前言:本文解決的問題

  • wait() await() sleep()這三個方法有申請區別

在找工作的各種筆試題目中,經常看到wait()、sleep()還有await(),功能都很相似,到底有什么區別?什么時候該用哪一種方法

1. wait() VS sleep()

wait和sleep的比較可以說是高頻面試題。方法原型分別為:

 public final native void wait(long timeout) throws InterruptedException;

 public static native void sleep(long millis) throws InterruptedException;

同:

  • 都是線程同步時會用到的方法,使當前線程暫停運行,把運行機會交給其它線程。
  • 如果任何線程在等待期間被中斷都會拋出InterruptedException
  • 都是native方法

異:

  • 所在類不同,wait()是Object超類中的方法;而sleep()是線程Thread類中的方法
  • 關鍵點是對鎖的保持不同,wait會釋放鎖;而sleep()並不釋放鎖
  • 喚醒方法不完全相同,wait依靠notify或者notifyAll、中斷發生、或者到達指定時間來喚醒;而sleep()則是到達指定的時間后被喚醒。
  • 使用的位置不同,wait只能用在同步代碼塊中,而sleep用在任何位置。

2. wait() VS await()

這兩個長得很像。await()的實現比較復雜。

  public final void await() throws InterruptedException {
            if (Thread.interrupted())
                throw new InterruptedException();
            Node node = addConditionWaiter();
            int savedState = fullyRelease(node);
            int interruptMode = 0;
            while (!isOnSyncQueue(node)) {
                LockSupport.park(this);
                if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                    break;
            }
            if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
                interruptMode = REINTERRUPT;
            if (node.nextWaiter != null) // clean up if cancelled
                unlinkCancelledWaiters();
            if (interruptMode != 0)
                reportInterruptAfterWait(interruptMode);
        }

先說下來源,await是ConditionObject類里面的方法,ConditionObject實現了Condition接口;而ReentrantLock里面默認有實現newCondition()方法,新建一個條件對象。該方法就是用在ReentrantLock中根據條件來設置等待。喚醒方法也是由專門的Signal()或者Signal()來執行。另外await會導致當前線程被阻塞,會放棄鎖,這點和wait是一樣的。

由於所在的超類不同使用場景也不同,wait一般用於Synchronized中,而await只能用於ReentrantLock鎖中,具體如下
wait()

          synchronized (obj) {
              while (<condition does not hold>)
               obj.wait(timeout);
             ... // Perform action appropriate to condition
         }

await()主要見上文。

3 notify signal

順便說下這二者的區別,notify使用來喚醒使用wait的線程;而signal是用來喚醒await線程。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM