1. 程式人生 > >java執行緒阻塞喚醒的四種方式

java執行緒阻塞喚醒的四種方式

java在多執行緒情況下,經常會使用到執行緒的阻塞與喚醒,這裡就為大家簡單介紹一下以下幾種阻塞/喚醒方式與區別,不做詳細的介紹與程式碼分析

  1. suspend與resume

    Java廢棄 suspend() 去掛起執行緒的原因,是因為 suspend() 在導致執行緒暫停的同時,並不會去釋放任何鎖資源。其他執行緒都無法訪問被它佔用的鎖。直到對應的執行緒執行 resume() 方法後,被掛起的執行緒才能繼續,從而其它被阻塞在這個鎖的執行緒才可以繼續執行。
    但是,如果 resume() 操作出現在 suspend() 之前執行,那麼執行緒將一直處於掛起狀態,同時一直佔用鎖,這就產生了死鎖。而且,對於被掛起的執行緒,它的執行緒狀態居然還是 Runnable。

  2. wait與notify

    wait與notify必須配合synchronized使用,因為呼叫之前必須持有鎖,wait會立即釋放鎖,notify則是同步塊執行完了才釋放

  3. await與singal

    Condition類提供,而Condition物件由new ReentLock().newCondition()獲得,與wait和notify相同,因為使用Lock鎖後無法使用wait方法

  4. park與unpark

    LockSupport是一個非常方便實用的執行緒阻塞工具,它可以線上程任意位置讓執行緒阻塞。和Thread.suspenf()相比,它彌補了由於resume()在前發生,導致執行緒無法繼續執行的情況。和Object.wait()相比,它不需要先獲得某個物件的鎖,也不會丟擲IException異常。可以喚醒指定執行緒。

總結

  • wait與await區別:

    • wait與notify必須配合synchronized使用,因為呼叫之前必須持有鎖,wait會立即釋放鎖,notify則是同步塊執行完了才釋放
    • 因為Lock沒有使用synchronized機制,故無法使用wait方法區操作多執行緒,所以使用了Condition的await來操作
  • Lock實現主要是基於AQS,而AQS實現則是基於LockSupport,所以說LockSupport更底層,所以使用park效率會高一些

這裡寫圖片描述