线程间通信

news2024/12/26 10:38:39

1、需求

  • 现在两个线程
  • 操作一个初始值为0的变量
  • 实现一个线程对变量增加1,一个线程对变量减少1
  • 交替,来10轮

2、多线程编程模板中

1)判断
2)干活
3)通知
线程间通信:
1.生产者+消费者
2.通知等待唤醒机制

3、synchronized实现两个线程

class ShareDataOne{
    private int number=0;

    public synchronized void incre() throws InterruptedException {
        //判断
        if(number!=0){
            this.wait();
        }
        //干活
        ++number;
        System.out.println(Thread.currentThread().getName()+
                "\t"+number);
        //通知
        this.notifyAll();

    }

    public synchronized void decre() throws InterruptedException {
        //判断
        if(number!=1){
            this.wait();
        }
        //干活
        --number;
        System.out.println(Thread.currentThread().getName()+
                "\t"+number);
        //通知
        this.notifyAll();

    }

}
/**
 * 现在两个线程
 * 操作一个初始值为0的变量
 * 实现一个线程对变量增加1,一个线程对变量减少1
 * 交替,来10轮
 *1、线程 操作 资源类
 * 2、高内聚低耦合
 * 1、判断
 * 2、干活
 * 3、通知
 *
 */
public class NotifyWaitDemo {
    public static void main(String[] args) {

        ShareDataOne shareDataOne = new ShareDataOne();
        new Thread(()->{
            for (int i = 1; i <=10 ; i++) {
                try {
                    shareDataOne.incre();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"AA").start();

        new Thread(()->{
            for (int i = 1; i <=10 ; i++) {
                try {
                    shareDataOne.decre();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"BB").start();


    }
}

4、 synchronized实现四个线程

(1)换成4个线程会导致错误,虚假唤醒

原因:在java多线程判断时,不能用if,程序出事出在了判断上面,
突然有一添加的线程进到if了,突然中断了交出控制权,
没有进行验证,而是直接走下去了,加了两次,甚至多次。

(2)解决办法

解决虚假唤醒:查看API,java.lang.Object
在这里插入图片描述

中断和虚假唤醒是可能产生的,所以要用loop循环,if只判断一次,while是只要唤醒就要拉回来再判断一次。if换成while
在这里插入图片描述

5、多线程编程模板下

注意多线程之间的虚假唤醒
在这里插入图片描述

6、正确代码

class ShareDataOne{
    private int number=0;

    public synchronized void incre() throws InterruptedException {
        //判断
        while(number!=0){
            this.wait();
        }
        //干活
        ++number;
        System.out.println(Thread.currentThread().getName()+
                "\t"+number);
        //通知
        this.notifyAll();

    }

    public synchronized void decre() throws InterruptedException {
        //判断
        while(number!=1){
            this.wait();
        }
        //干活
        --number;
        System.out.println(Thread.currentThread().getName()+
                "\t"+number);
        //通知
        this.notifyAll();
    }
}
/**
 * 现在两个线程
 * 操作一个初始值为0的变量
 * 实现一个线程对变量增加1,一个线程对变量减少1
 * 交替,来10轮
 *1、线程 操作 资源类
 * 2、高内聚低耦合
 * 1、判断
 * 2、干活
 * 3、通知
 *
 */
public class NotifyWaitDemo {
    public static void main(String[] args) {
        ShareDataOne shareDataOne = new ShareDataOne();
        new Thread(()->{
            for (int i = 1; i <=10 ; i++) {
                try {
                    shareDataOne.incre();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"AA").start();

        new Thread(()->{
            for (int i = 1; i <=10 ; i++) {
                try {
                    shareDataOne.decre();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"BB").start();

        new Thread(()->{
            for (int i = 1; i <=10 ; i++) {
                try {
                    shareDataOne.incre();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"CC").start();

        new Thread(()->{
            for (int i = 1; i <=10 ; i++) {
                try {
                    shareDataOne.decre();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"DD").start();
    }
}

7、lock实现线程间通信
在这里插入图片描述

Condition:查看API,java.util.concurrent

class BoundedBuffer {
   final Lock lock = new ReentrantLock();
   final Condition notFull  = lock.newCondition(); 
   final Condition notEmpty = lock.newCondition(); 
 
   final Object[] items = new Object[100];
   int putptr, takeptr, count;
 
   public void put(Object x) throws InterruptedException {
     lock.lock();
     try {
       while (count == items.length)
         notFull.await();
       items[putptr] = x;
       if (++putptr == items.length) putptr = 0;
       ++count;
       notEmpty.signal();
     } finally {
       lock.unlock();
     }
   }
 

8、lock版代码

class ShareDataOne{
    private int number=0;
    private Lock lock = new ReentrantLock();
    private Condition cd = lock.newCondition();

    public  void incre() throws InterruptedException {
        lock.lock();
        try {
            //判断
            while(number!=0){
                cd.await();
            }
            //干活
            ++number;
            System.out.println(Thread.currentThread().getName()+
                    "\t"+number);
            //通知
            cd.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }

    public  void decre() throws InterruptedException {
        lock.lock();
        try {
            //判断
            while(number!=1){
                cd.await();
            }
            //干活
            --number;
            System.out.println(Thread.currentThread().getName()+
                    "\t"+number);
            //通知
            cd.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Aski AI: 基于人工智能的在线AI工具平台

【产品介绍】 Aski AI是一个基于人工智能的在线AI工具平台&#xff0c;它可以帮助用户快速、准确、全面地解决各种问题。无论是学习、工作、生活、娱乐还是其他领域&#xff0c;只要输入你的问题&#xff0c;Aski AI就会为你提供最合适的答案。此外还提供AI文章写作&#xff0c…

BHQ1 Mal,BHQ2 Maleimide,BHQ3 Mal,马来酰亚胺修饰的BHQ试剂有哪些特点?

一、BHQ-1 Maleimide 产品描述&#xff1a; BHQ-1 Maleimide黑洞猝灭剂-1(BHQ-1)被归类为暗猝灭剂&#xff0c;该淬灭剂能够将一定距离内荧光基团发出的光全部吸收&#xff0c;实现对荧光信号的淬灭&#xff0c;所以可得到更强的特异性&#xff0c;更优化的信噪比。 中文名&a…

【正点原子STM32连载】 第四十五章 FLASH模拟EEPROM实验 摘自【正点原子】STM32F103 战舰开发指南V1.2

第四十五章 FLASH模拟EEPROM实验 STM32本身没有自带EEPROM&#xff0c;但是STM32具有IAP&#xff08;在应用编程&#xff09;功能&#xff0c;所以我们可以把它的FLASH当成EEPROM来使用。本章&#xff0c;我们将利用STM32内部的FLASH来实现第三十六章实验类似的效果&#xff0…

设计模式第18讲——中介者模式(Mediator)

目录 一、什么是中介者模式 二、角色组成 三、优缺点 四、应用场景 4.1 生活场景 4.2 java场景 五、代码实现 5.0 代码结构 5.1 抽象中介者&#xff08;Mediator&#xff09;——LogisticsCenter 5.2 抽象同事类&#xff08;Colleague&#xff09;——Participant 5…

nvm安装node

使用 Windows 系统的我选择使用其推荐的 nvm-windows 来管理 Node.js 版本。 在安装 nvm-windows 前&#xff0c;如果你的电脑中已经安装了 Node.js&#xff0c;那么可以选择卸载&#xff0c;也可以选择不卸载。因为在安装 nvm-windows 的过程中其会询问你是否需要将已安装的 N…

mysql数据库迁移到kingbase人大金仓

1. 启动数据迁移工具 2. 浏览器打开网址[http://localhost:8080/]进入可视化操作界面&#xff0c;在源数据库添加人大金仓数据库信息&#xff0c;测试成功后保存 3.在目标数据库填写需要同步的mysql数据库&#xff0c;添加对应的mysql数据库信息&#xff0c;测试成功后保存 4.在…

The Company Requires Superficial StudyPHP 打开执行PHP ②

作者 : SYFStrive 博客首页 : HomePage &#x1f4dc;&#xff1a; PHP MYSQL &#x1f4cc;&#xff1a;个人社区&#xff08;欢迎大佬们加入&#xff09; &#x1f449;&#xff1a;社区链接&#x1f517; &#x1f4cc;&#xff1a;觉得文章不错可以点点关注 &#x1f44…

自制游戏引擎

这是一个玩具 1. 引擎使用流程 SmallEngine是引擎的核心模块,封装渲染功能和场景管理功能等Editor是编辑器,类似unity和ue编辑器,能够动态添加对象和组件Sandbox是游戏播放器,能够运行游戏 2. SmallEngine 参考 https://www.bilibili.com/video/BV1KE41117BD/?spm_id_from333…

ARM实验-ARM主程序调用ARM/C语言子程序

一、实验名称&#xff1a;ARM主程序调用ARM/C语言子程序 二、实验目的&#xff1a; 了解ARM应用程序框架。了解ARM汇编程序函数和C语言程序函数相互调用时&#xff0c;遵循的ATPCS标准&#xff1b;了解和掌握ARM汇编程序调用C语言程序函数的基本方法&#xff1b;了解和掌握AR…

操作系统第4章 文件系统 知识点

UNIX系统不存一些具体的指针了 只存文件名和指向i结点的指针 这个删除和截断有什么区别 目录本来放在外存的&#xff0c;有文件打开表&#xff0c;从外存复制到内存的文件打开表中&#xff0c;用户想继续读的时候&#xff0c;不用再去外存搜索目录 访问文件打开表的索引叫文…

基于“SRP模型+”多技术融合在生态环境脆弱性评价模型构建、时空格局演变分析与RSEI 指数的生态质量评价及拓展应用

近年来&#xff0c;国内外学者在生态系统的敏感性、适应能力和潜在影响等方面开展了大量的生态脆弱性研究&#xff0c;他们普遍将生态脆弱性概念与农牧交错带、喀斯特地区、黄土高原区、流域、城市等相结合&#xff0c;评价不同类型研究区的生态脆弱特征&#xff0c;其研究内容…

大数据Doris(五十二):Doris数据导出案例和注意事项

文章目录 Doris数据导出案例和注意事项 一、Doris数据导出到HDFS案例 1、创建Doris表并插入数据 2、创建Export ,数据导出到 HDFS 3、查看任务 4、查看导出结果 二、Doris数据导出到本地案例 1、配置 fe.conf 2、Doris 数据导出到本地 三、注意事项 Doris数据导出案例…

kettle源码远程debug调试

一、kettle启动时指定debug端口号 windows下&#xff0c;修改bat执行文件&#xff0c;同理 linux修改sh执行文件 在java执行参数的末尾添加debug参数 address为debug端口 -Xdebug -Xnoagent -Djava.compilerNONE -Xrunjdwp:transportdt_socket,servery,suspendn,address9080然…

从渲染流程、数据处理结构聊聊Flutter性能优化

不可否认 Flutter 是一个非常强大的移动应用开发框架&#xff0c;我们在技术架构选型时就是选用的 Flutter&#xff0c;特别是跨端能力属实很优秀&#xff0c;but 也逐渐发现在复杂的应用程序实现中&#xff0c;App 的性能会受到一些影响。 其实这个问题&#xff0c;我们内部也…

SpringCloud入门实战(九)- SpringCloud Config配置中心

&#x1f4dd; 学技术、更要掌握学习的方法&#xff0c;一起学习&#xff0c;让进步发生 &#x1f469;&#x1f3fb; 作者&#xff1a;一只IT攻城狮 &#xff0c;关注我&#xff0c;不迷路 。 &#x1f490;学习建议&#xff1a;1、养成习惯&#xff0c;学习java的任何一个技术…

java List集合使用笔记

1、List集合的特点 有序集合、有序的序列&#xff0c;用户可以精准的控制元素插入的位置通过索引访问元素可以搜索元素与Set不同&#xff0c;List允许重复的元素存在 2、List集合特有的方法 add(索引,元素) remove(索引)&#xff1a;返回的是被删除的索引 get(索引)&#xf…

Arduino uno 环境配置 for Mac

1、IDE 在官网下载 官网地址&#xff1a;https://www.arduino.cc/en/software 看到钱&#x1f4b0;不要怕&#xff0c;只是问你捐不捐款&#xff0c;不收钱&#xff0c;你直接安装就行 &#xff08;你也可以捐一点&#xff5e;&#xff09; 安装之后 2、安装驱动 地址 &…

单片机-矩阵键盘密码锁

89C52RC芯片 1.矩阵按键输入正确密码&#xff0c;LCD1602右上角显示ok&#xff0c;错误显示Err。 涉及文件&#xff1a; 1.main.c (#include<regx52.h>) 2.lcd1602.c lcd1602.h 3.Delay.c Delay.h 4.MatrixKey.c MetrixKey.h 共7项 代码 main.c #…

此导入从不用作值,必须使用 “import type“ ,因为 “importsNotUsedAsValues“ 设置为 “error“。

前言 最近电脑更新了一次系统&#xff0c;重启后在 VsCode中打开项目 &#xff0c;发现原本正常的代码出现了一堆语法提示。网上搜了一下&#xff0c;没有找到关于此问题的回答&#xff0c;不知道我是不是第一个遇到的。在此记录一下这次的经历&#xff0c;如果有其他人遇到&a…

蓝桥杯专题-试题版含答案-【6174问题】【笨小熊】【鸡兔同笼】【小学生算数】

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 &#x1f449;关于作者 专注于Android/Unity和各种游…