当前位置: 首页 > news >正文

Java中的notify()与notifyAll()区别

Java中的notify()与notifyAll()区别

  • 一、notify()方法
    • 1.1 关键点
  • 二、notifyAll()方法
    • 2.1 关键点
  • 三、区别与选择
    • 3.1 区别
    • 3.2 选择
  • 四、实例演示


💖The Begin💖点点关注,收藏不迷路💖

一、notify()方法

notify()方法是Object类的一个方法,用于唤醒在此对象监视器上等待的单个线程。这里需要注意的是,notify()方法并不能指定唤醒哪个具体的线程,而是随机唤醒等待队列中的一个线程。因此,当只有一个线程在等待时notify()方法才显得有用。

1.1 关键点

  • 随机唤醒:唤醒在此对象监视器上等待的单个线程,但不保证是哪个线程。
  • 单一性:在多个线程等待时,只能唤醒一个线程。
  • 局限性:如果调用notify()时没有线程在等待,那么这个方法将不会有任何效果。

二、notifyAll()方法

notify()方法不同,notifyAll()方法会唤醒在此对象监视器上等待的所有线程。这意味着,一旦调用notifyAll(),所有因调用此对象的wait()方法而阻塞的线程都将被唤醒,并有机会重新获得对象的锁。

2.1 关键点

  • 全面唤醒:唤醒在此对象监视器上等待的所有线程。
  • 竞争锁:被唤醒的线程需要重新竞争对象的锁,只有获得锁的线程才能继续执行。
  • 确保性:确保至少有一个线程能继续运行,尤其是在多个线程等待时。

三、区别与选择

3.1 区别

  • 唤醒对象notify()唤醒一个线程,而notifyAll()唤醒所有线程。
  • 适用场景notify()适用于确切知道只有一个线程在等待的情况;而notifyAll()则适用于不确定有多少个线程在等待,或者希望所有等待的线程都能被唤醒并尝试继续执行的情况。

3.2 选择

  • 当只有一个线程会等待某个条件,并且只需要唤醒这个线程时,使用notify()
  • 当不知道有多少个线程在等待,或者希望所有等待的线程都有机会被唤醒并尝试继续执行时,使用notifyAll()

四、实例演示

假设有一个生产者-消费者模型,生产者线程生产产品后放入缓冲区,消费者线程从缓冲区中取出产品。

在这个模型中,如果只有一个消费者线程,可能使用notify()就足够了;但如果有多个消费者线程,那么使用notifyAll()将更为稳妥,因为它能确保所有等待的消费者线程都有机会被唤醒并尝试从缓冲区中取出产品。

下面是一个简单的生产者-消费者模型的Java实现,其中使用了notifyAll()来确保所有等待的消费者都能被唤醒:

import java.util.LinkedList;
import java.util.Queue;public class ProducerConsumerExample {// 使用一个队列作为缓冲区  private final Queue<Integer> buffer = new LinkedList<>();// 缓冲区容量  private final int capacity = 10;// 对象锁  private final Object lock = new Object();public static void main(String[] args) {ProducerConsumerExample example = new ProducerConsumerExample();// 创建并启动生产者线程  Thread producer = new Thread(() -> {for (int i = 0; i < 20; i++) {try {example.produce(i);} catch (InterruptedException e) {throw new RuntimeException(e);}}});// 创建并启动消费者线程  Thread consumer1 = new Thread(() -> {for (int i = 0; i < 10; i++) {try {example.consume();} catch (InterruptedException e) {throw new RuntimeException(e);}}});Thread consumer2 = new Thread(() -> {for (int i = 0; i < 10; i++) {try {example.consume();} catch (InterruptedException e) {throw new RuntimeException(e);}}});producer.start();consumer1.start();consumer2.start();}// 生产者方法  public void produce(int product) throws InterruptedException {synchronized (lock) {while (buffer.size() == capacity) {// 缓冲区满,生产者等待  lock.wait();}buffer.add(product);System.out.println("Produced: " + product);// 唤醒所有等待的消费者  lock.notifyAll();}}// 消费者方法  public void consume() throws InterruptedException {synchronized (lock) {while (buffer.isEmpty()) {// 缓冲区空,消费者等待  lock.wait();}Integer item = buffer.poll();System.out.println("Consumed: " + item);// 唤醒所有等待的生产者或消费者(虽然这里主要是生产者可能等待)  lock.notifyAll();}}
}

在这里插入图片描述


💖The End💖点点关注,收藏不迷路💖

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 探展2024世界人工智能大会之合合信息扫描黑科技~
  • Harmony学习(四)(应用程序框架基础)
  • 电影票房数据的获取,可以控制数量,并导出表格或csv
  • filebeat + logstash使用笔记
  • 优化PyCharm:让IDE响应速度飞起来
  • 一键生成视频并批量上传视频抖音、bilibili、腾讯(已打包)
  • 【vulnhub】The Ether: Evil Science靶机
  • 浦语提示词工程实践
  • 从文本到图像:深度解析向量嵌入在机器学习中的应用
  • 面试经验|问题
  • Linux配置go程序为service后台开机自启动
  • Spring统一返回类型中关于String的问题
  • linux源码编译qt6.5问题解决
  • 基于Spring boot + Vue的灾难救援系统
  • Mojo值的生命周期(Life of a value)详解
  • 分享的文章《人生如棋》
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • CSS进阶篇--用CSS开启硬件加速来提高网站性能
  • ES学习笔记(12)--Symbol
  • Java,console输出实时的转向GUI textbox
  • JavaScript的使用你知道几种?(上)
  • Lsb图片隐写
  • PHP的Ev教程三(Periodic watcher)
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • Three.js 再探 - 写一个跳一跳极简版游戏
  • 包装类对象
  • 第三十一到第三十三天:我是精明的小卖家(一)
  • 第十八天-企业应用架构模式-基本模式
  • 浮现式设计
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 让你的分享飞起来——极光推出社会化分享组件
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 详解移动APP与web APP的区别
  • 小而合理的前端理论:rscss和rsjs
  • 因为阿里,他们成了“杭漂”
  • 掌握面试——弹出框的实现(一道题中包含布局/js设计模式)
  • 中文输入法与React文本输入框的问题与解决方案
  • 自定义函数
  • AI算硅基生命吗,为什么?
  • Java性能优化之JVM GC(垃圾回收机制)
  • 国内开源镜像站点
  • ​Java并发新构件之Exchanger
  • ​猴子吃桃问题:每天都吃了前一天剩下的一半多一个。
  • ​无人机石油管道巡检方案新亮点:灵活准确又高效
  • #C++ 智能指针 std::unique_ptr 、std::shared_ptr 和 std::weak_ptr
  • #HarmonyOS:Web组件的使用
  • (007)XHTML文档之标题——h1~h6
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (Oracle)SQL优化基础(三):看懂执行计划顺序
  • (void) (_x == _y)的作用
  • (Windows环境)FFMPEG编译,包含编译x264以及x265
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (超详细)2-YOLOV5改进-添加SimAM注意力机制
  • (二)什么是Vite——Vite 和 Webpack 区别(冷启动)