Java 執行緒同步中的 notify() 方法及示例


簡介

Object 類包含 notify() 方法的定義。它只會喚醒一個正在等待某個專案的執行緒,然後該執行緒開始執行。可以使用執行緒類的 notify() 方法喚醒單個執行緒。當多個執行緒正在等待通知時使用 notify() 方法時,只有一個執行緒會實際收到通知,而其他執行緒則繼續等待。

讓我們一起討論 Java 執行緒同步中的 notify() 方法,以及它的用法和程式設計示例。我們將深入瞭解它如何改進執行緒同步和執行緒間通訊。

Java 中 notify() 方法的解釋

“notify()” 方法屬於 Java 中的 Object 類,用於促進執行緒間通訊和協調。當一個執行緒在某個物件上呼叫 notify() 時,它會喚醒一個在同一物件上呼叫 wait() 的等待執行緒。喚醒的執行緒從等待狀態變為可執行狀態,並且它將嘗試重新獲取物件的監視器鎖以繼續執行。

我們必須知道,notify() 方法不會選擇要喚醒哪個執行緒。喚醒執行緒的選擇取決於 JVM 的內部實現,並且可能在每個 Java 執行時環境之間有所不同。如果沒有任何執行緒在等待該物件,則 notify() 方法呼叫沒有任何效果。

使用 notify() 方法解決賣家和顧客問題

此特定程式屬於如何使用 notify() 方法解決賣家和顧客問題。

示例

import java.util.LinkedList;
import java.util.Queue;
public class CustomerItems 
{
   private final Object lock = new Object();
   private Queue<Integer> buffer = new LinkedList<>();
   private final int capacity = 10;
   public void produce() throws InterruptedException {
      synchronized (lock) {
         while (buffer.size() == capacity) 
         {
            lock.wait();
         }
         int items = 1; 
         buffer.add(items);
         System.out.println("Number of Sold items: " + items);
         lock.notify();
      }
   }
   public void consume() throws InterruptedException {
      synchronized (lock) {
         while (buffer.isEmpty()) {
            lock.wait();
         }
         int ValueofConsumeditem = buffer.poll();
         System.out.println("Number of Consumed items: " + ValueofConsumeditem);
         lock.notify();
      }
   }
   public static void main(String args []) 
   {
      CustomerItems example = new CustomerItems();

      Thread producerThread = new Thread(() -> {
         try {
            while (true) {
               example.produce();
               Thread.sleep(1000); 
            }
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      });
      Thread consumerThread = new Thread(() -> {
         try {
            while (true) {
               example.consume();
               Thread.sleep(1500); 
            }
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      });
      producerThread.start();
      consumerThread.start();
   }
}

輸出

Number of Sold items: 1
Number of Consumed items: 1
Number of Sold items: 1
Number of Consumed items: 1
Number of Sold items: 1
Number of Consumed items: 1
Number of Sold items: 1
Number of Sold items: 1
Number of Consumed items: 1
Number of Sold items: 1
Number of Consumed items: 1
Number of Sold items: 1
Number of Sold items: 1
Number of Consumed items: 1
Number of Sold items: 1
Number of Consumed items: 1
Number of Sold items: 1

首先,我們在程式中匯入了一些重要的包。

java.util.LinkedList;
java.util.Queue;

之後,我們定義了一個名為 CustomerItems 的類。在類中,我們建立了該類的物件並建立了一個連結串列。

private final Object lock = new Object();
private Queue<Integer> buffer = new LinkedList<>();

然後,我們聲明瞭一個名為 capacity 的變數,它是 final 和整數型別,併為該整數分配了一些值。然後,我們呼叫了一個名為 produce() 的函式,其中存在一個 interruptedExecution 並執行一些同步工作。

public void consume() throws InterruptedException

如果緩衝區已滿,使用者必須等到緩衝區為空。如果緩衝區為空,則使用者有權向該緩衝區輸入一些值。現在,我們只是列印了使用者儲存在緩衝區中的已使用值。

int ValueofConsumeditem = buffer.poll();
System.out.println("Number of Consumed items: " + ValueofConsumeditem)

然後,我們呼叫 main() 函式,並在該函式中建立了一個名為 example 的物件。

CustomerItems example = new CustomerItems ();

現在,我們建立了一個執行緒來執行此特定工作。

Thread producerThread = new Thread(() ->

並呼叫函式 example()。

example.produce();
Thread.sleep(1500);

現在,我們分別啟動了生產者執行緒和消費者執行緒。

producerThread.start();
consumerThread.start();

展示 Java notify() 方法的使用

在此特定程式設計示例中,我們將看到 notify() 方法的另一個應用。

示例

public class BossThread 
{
   public static void main (String args [])
   {
      WorkerThread workerThread = new WorkerThread();
      workerThread.start();
      synchronized (workerThread) {
         try {
            // Display message only
            System.out.println("we now wait for the WorkerThread to finish!!!");
            // we wait() method for the main thread 
            workerThread.wait();
         }
         catch (InterruptedException e) {
            e.printStackTrace();
         }
         // Print result by the WorkerThread 
         System.out.println("Result is: " + workerThread.getResult());
      }
   }
}
class WorkerThread extends Thread 
{
   private int output;
   @Override
   public void run()
   {
      synchronized (this) 
      {
         for (int mp = 0; mp < 20; mp++) 
         {
            output += mp;
         }
         // use notify() to wake up the waiting thread
         notify();
      }
   }
   public int getResult() {
      return output;
   }
}

輸出

we now wait for the WorkerThread to finish!!!
Result is: 190

在此程式中,首先我們定義了一個名為 BossThread 的類,並在類中呼叫了 main() 函式。在 main() 函式中,我們建立了一個執行緒並啟動了該執行緒。

WorkerThread workerThread = new WorkerThread();
workerThread.start();

現在,我們執行了一些同步工作,以系統的方式完成任務是非常重要的。

synchronized (workerThread) {
   try {
   // Display message only
   System.out.println("we now wait for the WorkerThread to finish!!!");

最後,我們只是列印了 workerthread 的結果。

System.out.println("Result is: " + workerThread.getResult());

之後,我們定義了另一個名為 WorkerThread 的類,它擴充套件了執行緒類。

class WorkerThread extends Thread	

在此類中,我們聲明瞭一個名為“output”的變數,它是 final 和整數型別。現在,我們執行了 run() 方法,並在 run() 函式中執行了一些同步工作。現在,我們使用 notify() 來喚醒等待執行緒,並呼叫另一個名為 getResult() 的函式以從該函式獲取所需的輸出。

public int getResult() {
   return output;
   }
}

結論

在本文中,我們學習了很多關於 notify() 方法線上程同步方面的配置和應用。線上程部分,同步是最關鍵的話題。為了正確學習同步主題,我們必須詳細瞭解 notify() 以涵蓋整個執行緒主題。

更新於: 2023年10月4日

242 次檢視

啟動您的 職業生涯

透過完成課程獲得認證

開始學習
廣告