重学java 42.多线程 等待唤醒机制案例分析

Strength is built under a heavy load,I am expecting to pick up all of my loads and travel on. 

                                                                                                                             —— 24.5.24

章节重点

1.会用wait和notify两个方法
2.会使用Lock锁对象
3.会利用Cal1able接口实现多线程
4.会使用线程池完成多线程

等待唤醒案例分析(线程之间的通信)

要求:

        一个线程生成,一个线程消费,不能连续生产和消费 ——> 等待唤醒机制(生产者,消费者)(线程之间的通信)

方法:

        void wait()线程等待,等待的过程中线程会释放锁,需要被其他线程调用notify方法将其唤醒,重新抢锁执行
        void notify()线程唤醒,一次唤醒一个等待线程;如果有多条线程等待,则随机唤醒一条等待线程

        void notifyAll():唤醒所有等待线程

wait和notify方法需要锁对象调用,所以需要用到同步代码块中,而且必须是同一个锁对象

案例:

        包子铺生产和消费的案例,一个线程生产包子,一个线程消费包子,但是不能连续生产,也不能连续消费(需要生产一个消费一个)

JavaBean

package S75ThreadWaitNotify;

public class BaoZiPu {
    // 包子的数目count
    private int count;
    // 是否有包子flag
    private boolean flag;

    public BaoZiPu() {
    }

    public BaoZiPu(int count, boolean flag) {
        this.count = count;
        this.flag = flag;
    }

    // getCount改成消费包子,直接输出包子数量count
    public void getCount() {
        System.out.println("消费了第"+count+"个包子");
    }

    // setCount改造成生产包子,count++
    public void setCount() {
        count++;
        System.out.println("生产了第"+count+"个包子");
    }

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }
}

生产线程

package S76ThreadWaitNotify;

// 实现Runnable接口
public class Product implements Runnable{
    private BaoZiPu baoZiPu;

    public Product(BaoZiPu baoZiPu){
        this.baoZiPu = baoZiPu;
    }
    @Override
    public void run() {
        // 定义一个死循环
        while(true) {
            try {
                Thread.sleep(100L);
            }catch (InterruptedException e){
                throw new RuntimeException(e);
            }


            // 同步代码块
            synchronized (baoZiPu){
                // 1.判断flag是否为true,如果是true,证明有包子,生产线程等待
                if(baoZiPu.isFlag()==true){
                    try{
                        baoZiPu.wait();
                    }catch(InterruptedException e){
                        throw new RuntimeException(e);
                    }
                }

                // 2.如果flag为false,则要开始生产
                baoZiPu.setCount();
                // 3.改变flag为true
                baoZiPu.setFlag(true);
                // 4.唤醒唤醒生产线程
                baoZiPu.notify();
            }
        }
    }
}

消费线程

package S76ThreadWaitNotify;

public class Consumer implements Runnable{
    private BaoZiPu baoZiPu;

    public Consumer(BaoZiPu baoZiPu){
        this.baoZiPu = baoZiPu;
    }

    @Override
    public void run() {
        while(true) {
            try {
                Thread.sleep(100L);
            }catch (InterruptedException e){
                throw new RuntimeException(e);
            }

            // 同步代码块
            synchronized (baoZiPu){
                // 1.判断flag是否为false,如果是false,证明没有包子,消费线程等待
                if(baoZiPu.isFlag()==false){
                    // 抛出异常
                    try{
                        baoZiPu.wait();
                    }catch(InterruptedException e){
                        throw new RuntimeException(e);
                    }
                }

                // 2.如果flag为true,则要开始消费
                baoZiPu.getCount();
                // 3.改变flag为false,消费完了,没有包子了
                baoZiPu.setFlag(false);
                // 4.唤醒消费线程
                baoZiPu.notify();
            }
        }
    }
}

Test

package S75ThreadWaitNotify;

public class Demo214Test {
    public static void main(String[] args) {
        // 变成同一个对象
        BaoZiPu baoZiPu = new BaoZiPu();

        Product product = new Product(baoZiPu);
        Consumer consumer = new Consumer(baoZiPu);

        Thread thread1 = new Thread(product);
        Thread thread2 = new Thread(consumer);

        thread1.start();
        thread2.start();
    }
}

运行结果:(先生产线程进行判断,若flag为false,则wait等待,让出锁让consume消费现场先执行,若消费线程的包子数量为0,则唤醒生产线程,consume等待)

也可以同步方法实现等待唤醒,直接在BaoZiPu函数中定义同步方法,也可以解决等待唤醒问题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/639315.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

视频监控汇聚平台LntonCVS通过GB/T28181国标协议实现视频监控平台的级联方案

近年来,随着网络视频监控应用范围的拓展,越来越多的政府部门和跨区域行业单位对视频监控的需求已经不局限于本地联网监控。他们正在探索在原有的本地联网监控基础上,建设省级乃至全国范围内的跨区域监控联网,以全面打造数据共享平…

这所211专硕22408复试线310分,学硕收调剂!辽宁大学计算机考研考情分析!

辽宁大学信息学院下设计算机科学与技术、电子信息科学与技术、通信工程、信息管理与信息系统、软件工程5个本科专业,有计算机软件与理论、计算机应用技术2个硕士学位授权点,软件工程和计算机技术两个专业硕士学位点,1个计算机应用研究所、1个…

【机器学习300问】94、什么是多任务学习?

一、多任务学习的定义 多任务学习(Multi-Task Learning, MTL)是一种机器学习范式,它允许一个模型同时学习执行多个相关但不完全相同的任务。这种方法的核心是:通过共享表示或权重,不同的任务可以在学习过程中相互促进&…

金蝶「起舞」,AI进化

能清晰感受到的是,金蝶仍然在不断进化,甚至伴随着AI时代的到来,它的进化信号愈发明显。 这些进化对应的具体动作是,把过去多年的服务模型整合成AI模型,把具体的服务“工艺”整理成流程编排能力,以及从740…

音视频及H264/H256编码相关原理

一、音视频封装格式原理: 我们播放的视频文件一般都是用一种封装格式封装起来的,封装格式的作用是什么呢?一般视频文件里不光有视频,还有音频,封装格式的作用就是把视频和音频打包起来。 所以我们先要解封装格式&#…

ECharts实现地图飞线

echarts版本:https://echarts.apache.org/zh/changelog.html v5.x.x版本:不提供china.js和china.json文件 v4.x.x版本:使用npm安装echarts,默认包含china.js和china.json文件 目录 一、Html工程 二、vue工程 三、vue工程 四、矢…

【错误解决】使用HuggingFaceInstructEmbeddings时的一个错误

起因:使用huggingface构建一个问答程序时出现的问题。 错误内容: 分析: 查看代码发现,HuggingFaceInstructEmbeddings和sentence-transformers模块版本不兼容导致。 可以明显看到方法参数不同。 解决: 安装sentenc…

windows平台vcpkg安装

1. 克隆vcpkg仓库 git clone https://github.com/microsoft/vcpkg 2.运行bootstrap-vcpkg.bat下载vcpkg.exe 3.运行验证 4.使用VCPKG安装OPENSSL 5.安装成功

【静态分析】在springboot使用太阿(Tai-e)03

参考:使用太阿(Tai-e)进行静态代码安全分析(spring-boot篇三) - 先知社区 1. JavaApi 提取 1.1 分析 预期是提取controller提供的对外API,例如下图中的/sqli/jdbc/vuln 先看一下如何用tai-e去获取router…

NFT Insider #131:Mocaverse NFT市值破3.5万ETH,The Sandbox 参加NFCsummit

引言:NFT Insider由NFT收藏组织WHALE Members(https://twitter.com/WHALEMembers)、BeepCrypto (https://twitter.com/beep_crypto)联合出品,浓缩每周NFT新闻,为大家带来关于NFT最全面、最新鲜、…

0基础学习Mybatis系列数据库操作框架——Mysql的Geometry数据处理之WKT方案

大纲 几何结构构建点点集合线线集合面面集合几何信息集合 TypeHandlerSQL操作写入操作读取操作完整XML Mapper测试代码建表SQL总结代码参考资料 WKT全称是Well-Known Text。它是一种表达几何信息的字符串内容。比如点可以用WKT表示为POINT (3 3);线可以用WKT表示为L…

uniapp使用内置的switch组件的问题

说明 开关选择器 属性说明 属性名类型默认值说明平台差异说明checkedBooleanfalse是否选中disabledBooleanfalse是否禁用不支持:抖音小程序、飞书小程序typeStringswitch 样式 有效值:switch、checkbox colorColorswitch的颜色,通css的co…

【Text2SQL 经典模型】X-SQL

论文:X-SQL: reinforce schema representation with context ⭐⭐⭐⭐ Microsoft, arXiv:1908.08113 X-SQL 与 SQLova 类似,使用 BERT style 的 PLM 来获得 representation,只是融合 NL question 和 table schema 的信息的方式不太一样&#…

响应式处理-一篇打尽

纯pc端响应式 pc端平常用到的响应式布局 大致就如下三种,当然也会有其他方法,欢迎评论区补充 将div height、width设置成100% flex布局 flex布局主要是将flex-wrap: wrap, 最后,你可以通过给子元素设置 flex 属性来控制它们的…

基于STM32实现智能风扇控制系统

目录 文章主题环境准备智能风扇控制系统基础代码示例:实现智能风扇控制系统 PWM控制风扇速度温度传感器数据读取串口通信控制应用场景:智能家居与环境调节问题解决方案与优化收尾与总结 1. 文章主题与命名 文章主题 本教程将详细介绍如何在STM32嵌入式…

Docker仅需3步搭建免费私有化的AI搜索引擎-FreeAskInternet!

简介 FreeAskInternet 是一个完全免费、私有且本地运行的搜索引擎,并使用 LLM 生成答案,无需 GPU。用户可以提出问题,系统会进行多引擎搜索,并将搜索结果合并到ChatGPT3.5 LLM中,并根据搜索结果生成答案。 什么是 Fr…

Windows11的这个地方暴露着你的隐私,把它关掉避免尴尬

前言 现在的电脑真的是越来越智能化!现在有很多小伙伴都是用着Windows11的吧!用习惯了Windows11之后,突然发现它还是挺顺手的。 但不知道你有没有发现,Windows11上面有个地方暴露着你的隐私。这个隐私可能是某个小姐姐的图片&am…

【EasyX】快速入门——消息处理,音频

1.消息处理 我们先看看什么是消息 1.1.获取消息 想要获取消息,就必须学会getmessage函数 1.1.1.getmessage函数 有两个重载版本,它们的作用是一样的 参数filter可以筛选我们需要的消息类型 我们看看参数filter的取值 当然我们可以使用位运算组合这些值 例如,我们…

sequence cache太小导致enq: SQ – contention

当业务卡的时候,发现大量等待事件为enq: SQ – contention,检查awr的top 5事件: sql语句对sequence的调用非常频繁: 对这些语句排查发现sequence cache值均为默认20,调大cache到1000值: SQL> select SE…

sql select获取mysql所有数据库,指定数据库下的所有表名

介绍一下 MySQL 8.0 中默认安装的几个系统数据库/模式。 当我们安装 MySQL 8.0 并初始化数据库之后,默认会创建以下系统数据库: mysql,存储了 MySQL 服务器正常运行所需的各种信息。 information_schema,提供了访问数据库元数据…