notify() 和 notifyAll() 是用于线程间的通信和协作的方法,它们之间的区别如下:
1、唤醒的对象数量不同
- notify() 方法唤醒正在等待该对象锁的单个线程。如果有多个线程在等待,只会唤醒其中一个线程,具体是哪个线程由 JVM 决定。
- notifyAll() 方法唤醒正在等待该对象锁的所有线程,将它们从等待池中全部移动到锁池中,同时让它们竞争获取该对象的锁。
2、使用场景不同
- notify() 通常用于满足特定条件下的唤醒,例如生产者-消费者模型中的消费者线程。
- notifyAll() 通常用于广播通知,通知所有等待线程,例如生产者-消费者模型中的生产者线程。
下面是一个简单的示例,演示了 notify() 和 notifyAll() 的使用:
public class NotifyExample { public static void main(String[] args) { Message message = new Message(); Thread threadA = new Thread(new WaitingThread("Thread A", message)); Thread threadB = new Thread(new WaitingThread("Thread B", message)); threadA.start(); threadB.start(); try { Thread.sleep(2000); // 等待2秒钟,确保两个线程都开始等待了 } catch (InterruptedException e) { e.printStackTrace(); } Thread threadC = new Thread(new NotifyingThread("Thread C", message)); threadC.start(); } static class Message { private boolean ready = false; public synchronized void waitUntilReady() { while (!ready) { try { wait(); // 线程进入等待状态,等待通知 } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + " is now processing the message."); // 收到通知后处理消息 } public synchronized void notifyReady() { ready = true; // 设置标志位,表示消息已准备好 // notify(); // 唤醒单个等待线程 notifyAll(); // 唤醒所有等待线程 } } static class WaitingThread implements Runnable { private String name; private Message message; public WaitingThread(String name, Message message) { this.name = name; this.message = message; } public void run() { System.out.println(name + " is waiting for the message..."); // 输出线程正在等待消息 message.waitUntilReady(); // 线程等待消息准备 } } static class NotifyingThread implements Runnable { private String name; private Message message; public NotifyingThread(String name, Message message) { this.name = name; this.message = message; } public void run() { System.out.println(name + " is preparing the message..."); // 输出线程正在准备消息 try { Thread.sleep(1000); // 模拟消息准备时间 } catch (InterruptedException e) { e.printStackTrace(); } message.notifyReady(); // 唤醒等待的线程 System.out.println(name + " has notified other threads."); // 输出线程已通知其他线程 } } }
上面的代码中,对每个关键步骤进行了详细的注释说明。通过这段代码,我们可以看到:
- Message 类是一个共享资源类,有一个 ready 标志位表示消息是否已准备好。
- waitUntilReady() 方法用于让线程等待消息准备完毕,使用 while 循环来确保在多线程环境下避免虚假唤醒。
- notifyReady() 方法用于标记消息已准备好,并通过 notify() 或 notifyAll() 唤醒等待的线程。
- WaitingThread 类是一个等待线程,通过调用 message.waitUntilReady() 方法进入等待状态,等待消息准备。
- NotifyingThread 类是一个通知线程,它负责准备消息并调用 message.notifyReady() 唤醒等待的线程。
在示例中,创建了两个等待线程(Thread A 和 Thread B)和一个通知线程(Thread C)。当线程 A 和线程 B 调用 waitUntilReady() 方法后,它们会进入等待状态,等待消息准备完毕的通知。而线程 C 在准备好消息后调用 notifyReady() 方法来唤醒等待的线程。
如果使用 notify(),只会唤醒其中一个等待线程(Thread A 或 Thread B),并输出 “Thread A is now processing the message.” 或 “Thread B is now processing the message.”。而如果使用 notifyAll(),则会同时唤醒所有等待线程,并输出 “Thread A is now processing the message.” 和 “Thread B is now processing the message.”。
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/16879.html