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() 以涵蓋整個執行緒主題。