并发编程 - 等待/通知机制

用OpenNI2获取奥比中光Astra Pro及 Astra Pro SM输出的深度图(win,linux arm64 x64平台) 搞了一个奥比中光Astra Pro,想在windows平台,和linux rk3588 上获取深度信息,之前的驱动下载已经不好用了。 阅读详情

一、为啥需要等待 - 通知机制

假设线程没拿到锁,一直循环尝试去获取锁,这样效率是很低的,如果有通知机制,那么得到通知了,再执行即可。

二、何为等待 - 通知

如现实中,医院就医顺序:
1、患者挂号,等待叫号。 (等锁)
2、患者被叫号,医生诊治。 (拿到锁)
3、医生问诊,开检查单。(线程缺少执行条件,释放锁)
4、患者检查完,重新等待叫号。(重新尝试拿锁)
5、患者被叫好,医生诊治。(拿锁-执行)

三、如何实现等待 - 通知?

synchronized 配合wait(),notify(),notifyAll()来实现。
在这里插入图片描述
wait():当一个线程拿到锁,进入临界区后,由于条件不满足,进入阻塞状态,然后进入等待队列中,线程在进入等待队列的同时,会释放自己所持有的锁。
notify():条件满足了,随机通知等待队列中的一个线程,风险是可能会导致有的线程永远也通知不到。
notifyAll():条件满足了,通知等待队列中的所有线程。

转账代码如何优雅的实现等待/通知?

管理员代码:
package exercise_02_0707;

import java.util.ArrayList;
import java.util.List;

// 单例模式
public class Allocator {
private volatile static Allocator allocator = null; //volatitle 解决指令重排序的问题
private static List lockList = new ArrayList<>();

private Allocator() {
}        // 构造方法私有

public static Allocator getAllocator() { //synchronized  保证线程安全
    if (allocator == null) {
        // 保证所有线程都可以进入,不会因为锁方法而把类锁上,也可以过滤很多,提高性能
        synchronized (Allocator.class) { //开始锁住
            if (allocator == null) { //防止两个线程同城到达if,又出现线程不安全的问题,双重检查锁
                allocator = new Allocator();
            }
        }
    }
    return allocator;
}

// 拿到资源
public synchronized void getLock(Object a, Object b) throws InterruptedException {
    // while循环,notifyAll通知了之后,需要不断遍历等待队列中有哪些条件是满足了的
    while (lockList.contains(a) || lockList.contains(b)) {
        wait();
    }
    lockList.add(a);            System.out.println(Thread.currentThread().getName() + " wait");

    lockList.add(b);
}

// 释放资源
public synchronized void removeLock(Object a, Object b) {
    lockList.remove(a);
    lockList.remove(b);
    notifyAll();
    System.out.println(Thread.currentThread().getName() + " notifyAll");
}

}

账户代码及测试:

package exercise_02_0707;

public class AccountNew {
    private Integer balance = 10000; // 账户余额
    // 转账操作
    void transfer(AccountNew account2, int amt) throws InterruptedException {
        Allocator.getAllocator().getLock(this, account2);
        synchronized (this) {
            synchronized (account2) {
                account2.balance += amt;
                this.balance -= amt;
            }
        }
        System.out.println(Thread.currentThread().getName() + " over");
        Allocator.getAllocator().removeLock(this, account2);
    }

    public static void main(String[] args) {
        AccountNew account = new AccountNew();
        AccountNew account2 = new AccountNew();
        Thread a = new Thread(()->{
            try {
                account.transfer(account2,100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread b = new Thread(()->{
            try {
                account2.transfer(account,90);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        Thread c = new Thread(()->{
            try {
                account.transfer(account2,90);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        a.start();
        b.start();
        c.start();
    }
}

执行结果:
在这里插入图片描述

四、wait和sleep的区别

1、sleep方法属于Thread类,wait方法则属于Object类;
2、sleep不会释放锁,但是wait会;
3、sleep方法必须指定时间;
4、sleep随时可以用,wait用在同步方法和同步块中;
5、sleep方法暂停执行指定的时间,让出cpu给其他线程,但是监控状态依然保持,等到时间到了就会自动恢复运行状态。

addr2line解析不出来行号的解决方式(汇编解析高阶版) 摘要:本文针对AEC crash问题中addr2line无法解析行号的情况,通过llvm-addr2line和反汇编分析,定位到CamX::AECBEStats17::AdjustROIParams函数中的乘法溢出问题。关键发现包括: 常规addr2line只能解析到函数名但无具体行号 llvm-addr2line解析出多个可能溢出点(行196/204/211/218/270/271) 反汇编显示6个条件分支跳转到溢出处理函数 源码分析确认这些位置均存在乘法运算 最终通过汇编级调试工具成功定位UBsan报告 阅读详情

相关推荐

高通QNN SDK实战:从PyTorch模型到Snapdragon设备的完整部署指南

本文提供了一份详尽的高通QNN SDK实战指南,手把手教你如何将PyTorch模型高效部署到Snapdragon设备。内容涵盖从环境搭建、模型转换、量化优化到多后端部署与性能评测的完整流程,旨在帮助移动AI开发者打通模型落地的“最后一公里”,充分发挥高通平台的硬件加速潜力。

pz8901234的博客 1283

【多线程】线程通信之等待/通知机制

一、概念        线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能成为一个整体。线程间的通信就是成为整体的必用方案之一。可以说,使线程进行通信后,系统之间的交互性会更强大,在大大提高CPU利用率的同时还会使开发人员对各线程任务在处理的过程中进行有效的把控和监督。 二、线程的执行模式        1、互不通信的多线程模式        多个线程会在系统中并发执行。线程

柠檬树 2283

别再死记硬背菜单了!用Workbench搞定你的第一个ANSYS结构分析(附模型文件)

本文为零基础用户提供使用ANSYS Workbench完成第一个结构分析的完整指南。通过悬臂梁案例详细讲解从几何导入、材料定义、网格划分到边界条件设置的全流程,帮助初学者快速掌握有限元分析的基本操作,并附赠实用模型文件。

weixin_34233974的博客 307

并发编程之同步锁

每个对象或者类都对应一个同步锁,在进入使用synchronize方法或者synchronize代码块的线程会持有相应的锁,此时其他想要进入同步方法或同步代码块时必须等待(即同步阻塞,被放进lock pool);锁的情况有一下几种1 同步非静态方法:    此类方法为对象调用,使用的是对象级别的锁,而且该锁为线程中调用此方法的对象对应的锁(this),来看一个例子public class LockD...

胃小的博客 323

zabbix6.0.4拓扑图链路显示流量

1. 背景介绍 网络流量监控是网络管理员必备功课,以前研究cacti的weathermap插件,网络流量大小和拥塞情况一清二楚,随着cacti的没落,weathermap插件也不能再继续使用,此时就需要学习了解新的替代方案。 经过研究和实际测试,发现zabbix的拓扑图有这个功能。 以下验证了zabbix的拓扑图显示线路流量的功能。 2. Zabbix 6显示拓扑图流量过程 选择监测-拓扑图 点进Local ne...

u013930899的博客 8481

手撕代码系列:Conv2D

在实际的神经网络中,每个卷积核都会对应一个偏置值。这意味着如果网络有多个卷积核,每个卷积核的输出都可以加上对应的偏置。

qq_55794606的博客 909

Java并发编程 —— 死锁问题、线程等待

线程的状态转换流程: 死锁 定义:在多线程编程中(两个或两个以上的线程),因为资源抢占而造成资源无限等待的问题 线程和锁的关系 —— 1 对 多:一个线程可以拥有多把锁;而一把锁只能被一个线程拥有 排查死锁的工具: 1、jconsole 2、jvisualvm 3、jmc 手写一个死锁的关键步骤: 1、获取锁A 2、线程休眠 3、获取锁B package Thread; /** * 实现一个死锁 * */ public class ThreadDemo16 { public

MercuryG的博客 400

i.MX6ULL驱动开发 | 31 - Linux内核网络设备驱动框架

net_device结构体在内核中指代一个网络设备,定义在,是一个非常大的结构体,包含网络设备的属性描述和操作接口,其中一些关键的成员如下。Linux在轮询处理机制和中断处理机制的基础上,提出了一种高效的网络处理技术NAPI。NAPI的核心思想是不全部采用中断来读取网络数据,而是采用中断来唤醒数据接收服务程序,在接收服务程序中采用poll的方法来轮询处理数据。提高短数据包的接收效率,减少中断处理的时间。...

Mculover666的博客(嵌入式) 1103

并发-JUC

并发vs并行的区别并发concurrency多线程同时操作同一个资源,并不是真正的同时操作,而是交替操作,单核CPU的情况下,资源按时间分配给多个线程。并行parallellism是真正的多个线程同时执行,多核CPU,每个线程使用一个CPU资源来运行。并发编程描述的是一种使系统允许多个任务可以在重叠的时间段内执行设计结构,不是指多个任务在同一时间段内执行,而是指系统具备处理多个任务在同一时间内同时执行能力。高并发是指我们设计的程序,可以支持海量任务的执行在时间段上重叠的情况。...

pilipala_biu的博客 316

【物联网技术】ESP8266 ESP-01/01s 固件下载烧录+STM32串口通信接线

ESP8266 ESP-01/01s 工作模式接线与MQTT固件下载烧录接线

嵌入式阿齐Archie 3万+

万字长文告诉新手如何学习Python图像处理(上篇完结 四十四) | 「Python」有奖征文

这篇文章是图像处理的最后一篇文章,后面我们将进入新的章节。图像处理文章主要讲解的图像处理方法包括图像几何运算、图像量化采样、图像点运算、图像形态学处理、图像增强、图像平滑、图像锐化、图像特效、图像分割、傅里叶变换与霍夫变换、图像分类等。个人感觉如果你是编程初学者、Python初学者或图像处理爱好者,这个系列真心适合你学习,并且这篇文章算是Python图像处理的学习路线,希望您喜欢。

杨秀璋的专栏 2万+

java并发编程基础之等待通知机制wait/notify原理分析

一个线程修改了一个对象的值,而另一个线程感知了变化,然后进行了相应的操作,整个过程开始于一个线程,结束于另一个线程。前者是生产者,后者是消费者,这种模式在功能层面上实现了解耦。 有下面一段代码,大家可以根据执行的结果和注释很清晰的明确这个wait和notify的工作机制,wait等待释放锁。代码如下,不再做具体描述: pac...

tom有cat 1436

我用GPT-5.5十分钟就搞定了论文创新点!全靠这三个提示词

各位同仁好,我是七哥。一个在高校里从事人工智能 相关领域研究,钻研用大模型AI实操的学术人。可以和七哥交流学术写作或Gemini、GPT、Claude 等大模型 学术实操相关问题,多多交流,相互成就,共同进步。多数研究者一写创新点就总觉得只有提出了全新的理论、颠覆了整个领域,才算真正的创新。但学术研究里的创新,有一半不是从零创造的,是在前人工作的基础上,准确找到还没人解决、或者没解决好的问题,而且真正能立住的创新通常都离不开以下这三个问题。第一,前人到底缺了什么。

智能AI让学术科研更容易 707

超强图文|并发编程【等待/通知机制】就是这个feel~

点击上方“方志朋”,选择“设为星标”回复”666“获取新整理的面试文章你有一个思想,我有一个思想,我们交换后,一个人就有两个思想If you can NOT explain it simp...

方志朋的博客 115

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

队列和通知区别_超强图文并发编程【等待/通知机制】就是这个feel

你有一个思想,我有一个思想,我们交换后,一个人就有两个思想If you can NOT explain it simply, you do NOT understand it well enough现陆续将Demo代码和技术文章整理在一起 Github实践精选 ,方便大家阅读查看,本文同样收录在此,觉得不错,还请Star?并发编程为什么会有等待通知机制上一篇文章说明了 Java并发死锁解...

weixin_30920223的博客 150

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

并发编程-等待/通知机制

线程之间相互配合,完成某项工作,比如:一个线程修改了一个对象的值,而另一个线程感知到了变化,然后进行相应的操作,整个过程开始于一个线程,而最终执行又是另一个线程。前者是生产者,后者就是消费者,简单的办法是让消费者线程不断地变量是否符合预期在while循环中设置不满足的条件,如果条件满足则退出while循环,从而完成消费者的工作。却存在如下问题:1)难以确保及时性。2)难以降低开销。如果降低睡眠的时间,比如休眠1毫秒,这样消费者能更加迅速地发现条件变化,但是却可能消耗更多的处理器资源,造成了无端的浪费。

weixin_58482311的博客 113

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

java并发编程笔记:等待/通知机制

前言:一个线程修改了一个对象的值,而另一个线程感知到变化,然后进行相关操作。前者是生产者,后者是消费者,这种模式隔离了做什么和怎么做,在功能层面上实现了解耦,体系结构上具备了良好的伸缩性。在java中使用等待通知机制实现类似功能。等待通知机制:是指一个线程A调用了对象O的wait()方法进入等待状态,而另一个线程B调用了对...

weixin_41457434的博客 140

《Java并发编程的艺术》读书笔记:等待/通知机制

《Java并发编程的艺术》读书笔记:等待/通知机制 看这本书之前,对wait和notify认识大概就是,调用wait的线程A堵塞之后,一旦另外有线程调用notify方法。线程A会立马从wait方法处返回。看完这本书后。发现自己的认识实在太肤浅了。。。。。。 线程调用wait()后,会释放已经获得的锁。同一时候进入Waiting...

weixin_30338497的博客 96

java并发编程:等待/通知机制

对等待/通知机制做个总结:    一个线程修改了一个对象的值,而另一个线程感知到了变化,然后进行相应的操作,整个过程开始于一个线程,而最终执行又是另一个线程。前者是生产者,后者就是消费者,这种模式隔离了“做什么(what)”和“怎么做(how)",在功能层面上实现了解耦,体系结构上具备了良好的伸缩性,但是在java语言中如何实现类似的功能那?    简单的方法是让消费者线程不断地循环检查变量是否符...

蕉下客 661

java等待_Java并发编程 | 线程间通信,等待/通知机制

一、概念简介1、线程通信在操作系统中,线程是个独立的个体,但是在线程执行过程中,如果处理同一个业务逻辑,可能会产生资源争抢,导致并发问题,通常使用互斥锁来控制该逻辑。但是在还有这样一类场景,任务执行是有顺序控制的,例如常见的报表数据生成:启动数据分析任务,生成报表数据;报表数据存入指定位置数据容器;通知数据搬运任务,把数据写入报表库;该场景在相对复杂的系统中非常常见,如果基于多线程来描述该过程,则...

weixin_39535752的博客 67

并发编程01-深入理解Java并发/线程等待/通知机制

比如, 互联网服务架构在处理一次对外部业务请求的响应, 往往需要分布在不 同机器上的大量服务共同协作来实现,也就是我们常说的微服务, 这种服务细 分的架构在减少单个服务复杂度、 增加复用性的同时, 也不可避免地增加了服 务的数量, 缩短了留给每个服务的响应时间。以 前处理一个请求可以允许花费很长时间在单体应用中, 具有这种线程切换的成本也是无伤大雅的, 但现在在每个请求本身的执行时间变得很短、 数量变得很多 的前提下, 用户本身的业务线程切换的开销甚至可能会接近用于计算本身的开销, 这就会造成严重的浪费。

程序员江小北 1232

队列和通知区别_【并发编程系列6】Condition队列原理及await和singal(等待/唤醒)机制源码分析...

前言每一个Java对象都拥有一组监视器方法(定义在java.lang.Object上),主要包括wait()、 wait(long timeout)、notify()以及notifyAll()方法,这些方法与synchronized同步关键字配合,可以实现线程之间的通信(等待/通知)机制。在前一篇文章中我们介绍了Lock对象的实现类ReentrantLock和AQS队列实现原理,而Loc...

weixin_42107561的博客 291
上一篇: 并发编程 - 死锁如何处理
下一篇: 并发编程 - Java线程的一大堆
1024个秘密
博客等级 码龄9年 26粉丝 111原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值