<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] ## 簡介 Java Object對象中的wait,notify,notifyAll是定義在Object類的實例方法,用于**控制線程狀態**。 **三個方法都必須在synchronized 同步關鍵字所限定的作用域中調用**,否則會報錯java.lang.IllegalMonitorStateException ,意思是因為沒有同步,所以線程對對象鎖的狀態是不確定的,不能調用這些方法。 **wait** 表示持有對象鎖的線程A準備釋放對象鎖權限,釋放cpu資源并進入等待。 **notify** 表示持有對象鎖的線程A準備釋放對象鎖權限,通知jvm喚醒某個隨機競爭該對象鎖的線程X。 線程A synchronized 代碼作用域結束后,線程X直接獲得對象鎖權限,其他競爭線程繼續等待(即使線程X同步完畢,釋放對象鎖,其他競爭線程仍然等待,直至有新的notify ,notifyAll被調用)。 **notifyAll** 表示持有對象鎖的線程A準備釋放對象鎖權限,通知jvm喚醒所有競爭該對象鎖的線程 線程A synchronized 代碼作用域結束后,jvm通過算法將對象鎖權限指派給某個線程X,所有被喚醒的線程不再等待。線程X synchronized 代碼作用域結束后,之前所有被喚醒的線程都有可能獲得該對象鎖權限,這個由JVM算法決定 ## Demo ~~~ ublic class WaitNotifyCase { public static void main(String[] args) { final Object lock = new Object(); new Thread(new Runnable() { @Override public void run() { System.out.println("thread A is waiting to get lock"); synchronized (lock) { try { System.out.println("thread A get lock"); TimeUnit.SECONDS.sleep(1); System.out.println("thread A do wait method"); lock.wait(); System.out.println("wait end"); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); new Thread(new Runnable() { @Override public void run() { System.out.println("thread B is waiting to get lock"); synchronized (lock) { System.out.println("thread B get lock"); try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } lock.notify(); System.out.println("thread B do notify method"); } } }).start(); } } ~~~ ## 進入wait/notify方法之前,為什么要獲取synchronized鎖 我們知道wait/notify是為了線程間協作而設計的,當我們執行wait的時候讓線程掛起,當執行notify的時候喚醒其中一個掛起的線程,**那需要有個地方來保存對象和線程之間的映射關系**(可以想象一個map,key是對象,value是一個線程列表) 當調用這個對象的wait方法時,將當前線程放到這個線程列表里,當調用這個對象的notify方法時從這個線程列表里取出一個來讓其繼續執行 這樣看來是可行的,也比較簡單,那現在的問題這種映射關系放到哪里? lock.wait()方法通過調用native方法wait(0)實現,其中接口注釋中有這么一句: ``` The current thread must own this object’s monitor. ``` 表示線程執行lock.wait()方法時,必須持有該lock對象的ObjectMonitor(前文已經提及,每個鎖對象(這里指已經升級為重量級鎖的對象)都有一個ObjectMonitor(對象監視器)。也就是說每個線程獲取鎖對象都會通過ObjectMonitor) 如果wait方法在synchronized代碼中執行,該線程很顯然已經持有了monitor。 從而包含了“ 進入wait/notify方法之前,為什么要獲取synchronized鎖”,synchronized代碼塊通過javap生成的字節碼中包含 *monitorenter 和 monitorexit指令。其中執行monitorenter指令可以獲取對象的monitor ## 參考資料 [Java并發編程:Object.wait/notify](https://blog.csdn.net/fei20121106/article/details/83268434)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看