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 次查看

启动您的 职业生涯

通过完成课程获得认证

开始学习
广告