Menu
快讀
  • 旅遊
  • 生活
    • 美食
    • 寵物
    • 養生
    • 親子
  • 娛樂
    • 動漫
  • 時尚
  • 社會
  • 探索
  • 故事
  • 科技
  • 軍事
  • 国际
快讀

阿裏面試題,爲什麽wait()方法要放在同步塊中?

2021 年 3 月 11 日 果哥玲妹浪迹天涯

某天我在***的時候,突然有個小夥伴微信上說:“哥,阿裏面試又又挂了,被問到爲什麽wait()方法要放在同步塊中,沒答出來!”

阿裏面試題,爲什麽wait()方法要放在同步塊中?

但是,爲毛呢??我也沒去了解過。

機智如我立刻假裝正在開會忙得不可開交,回了一條:“開會中,等會和你細說。”

阿裏面試題,爲什麽wait()方法要放在同步塊中?

這就是所謂的lost wake up問題。

那麽怎麽解決這個問題呢?

現在我們應該就能夠看到,問題的根源在于,消費者在檢查count到調用wait()之間,count就可能被改掉了。

這就是一種很常見的競態條件。

很自然的想法是,讓消費者和生産者競爭一把鎖,競爭到了的,才能夠修改count的值。

于是生産者的代碼是:

tryLock() count+1 notify() releaseLock()

消費者的代碼是:

tryLock() while(count <= 0) wait() count-1 releaseLock

注意的是,我這裏將兩者的兩個操作都放進去了同步塊中。

現在來思考一個問題,生産者代碼這樣修改行不行?

tryLock() count+1 notify() releaseLock()

答案是,這樣改毫無卵用,依舊會出現lost wake up問題,而且和無鎖的表現是一樣的。

終極答案

所以,我們可以總結到,爲了避免出現這種lost wake up問題,在這種模型之下,總應該將我們的代碼放進去的同步塊中。

Java強制我們的wait()/notify()調用必須要在一個同步塊中,就是不想讓我們在不經意間出現這種lost wake up問題。

不僅僅是這兩個方法,包括java.util.concurrent.locks.Condition的await()/signal()也必須要在同步塊中:

private ReentrantLock lock = new ReentrantLock(); private Condition condition = lock.newCondition(); @Test public void test() { try { condition.signal(); } catch (Exception e) { e.printStackTrace(); } }

相關文章:

  • 這位「親美反華」的鄰國前總統,終於等到了「算帳」的時候
  • 全島“一罩難求”的時候,聯邦樂尚雅思居然豪送口罩,一送一整盒?
  • 當孩子說“我不會,我不行”的時候,三種思維方式撬動自信心
  • 史上最全iPhoneX 神吐槽錦集,笑不sei你
  • 西班牙網紅産品大揭秘
  • ▶ 47歲天津首富去世!臨走時給身邊的人說的話!所有人都沉默了!
熱點

發佈留言 取消回覆

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

©2026 快讀 | 服務協議 | DMCA | 聯繫我們