簡體   English   中英

Java 中 wait() 和 notifyAll() 的行為?

[英]Behavior of wait() and notifyAll() in Java?

請注意,這不是實際情況。 我根據我的實際實現創建了一個示例場景,以便於查看。 我也已經得到了預期的 output 。 但是,我需要澄清一些關於 Java 中的wait()notifyAll()方法的概念。 (在這里,這兩個線程都將在主線程中同時啟動 run 方法。)據我所知,由於線程 B 正在休眠,因為您可以在初始階段看到 reamingCount 是 400。

所以線程 B 將調用它的MUTEX.wait()並繼續它的睡眠,直到某個其他線程調用notify()notifyAll() ,然后在剩余計數減為 0 后,線程 A 將調用MUTEX.notifyAll(); 喚醒線程 B 和MUTEX.wait()以釋放其已授予的鎖,並且 go 進入休眠狀態,直到線程 B 通知它。

當我通過線程 A 調用MUTEX.notifyAll()時,線程 B 不會在線程 A 調用MUTEX.wait()之前喚醒並繼續其任務嗎?

我的意思是,您可以看到當線程 A 調用MUTEX.notifyAll()時,線程 B 將喚醒並再次檢查 while 循環中的條件是真還是假。 因此,由於剩余計數等於 0,線程 B 將退出 while 循環並在線程 A 調用wait()之前繼續其任務。 這種情況不會破壞wait()的原則嗎? 據我所知,線程 B 只能在線程 A 調用wait()時繼續執行。

public class A implements Runnable{

    public static volatile remainingCount =400;
    private final Object MUTEX;//Both class A and B holds the same object mutex

    private void methodA(){

         synchronized(MUTEX){
             
              while(remainingCount == 0){

                     MUTEX.notifyAll();
                     MUTEX.wait();
              }

              //Perform it's usual task.In here remaining count will decrement during the process.
              

        }
      @Override
      public void run() {

        while(true){
          methodA();
        }
     }
   }
}
public class B implements Runnable{

         private final Object MUTEX;//Both class A and B holds the same object mutex

         private void methodB(){
              synchronized(MUTEX){

                   while (A.remainingCount != 0) {
                        try {
                    
                               MUTEX.wait();
                     
                        } catch (InterruptedException ex) {
                               Logger.getLogger(InkServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
                        }
                   }
                      //incrementing the A.remainingCount 

                      MUTEX.notifyAll();
 
            }
            
           @Override
           public void run() {

                  while(true){
                     methodB();

                   }
             }
}

當持有鎖的線程在鎖定的 object 上調用wait()時,線程被添加到對象的等待集中並釋放鎖。

當持有鎖的線程調用notify()並且等待集不為空時,等待集中的線程被選中並移除。 同樣,調用notifyAll()會從等待集中刪除所有線程。

注意:線程也可以通過調用thread.interrupt()從等待集中移除。

當一個線程從等待集中移除並開始運行時,第一步是重新獲取鎖。 這發生在從wait()返回之前。

在調用notify()notifyAll()的線程通過調用wait()或退出同步塊釋放鎖之前,這不會發生。

因此,雖然您的線程 B 已啟用運行,但它實際上不會從wait()返回,直到線程 A 通過調用MUTEX.wait()釋放鎖。 同樣,當 B 調用MUTEX.notifyAll()時,線程 A 可以運行,但在線程 B 退出synchronized(MUTEX)塊之前不會從wait()返回。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM