系列五、线程间通信

一、synchronized实现

1.1、案例一(2个线程交替对变量执行+1、-1操作,来10轮)

1.1.1、资源类ShareDataOne

/*** @Author : 一叶浮萍归大海* @Date: 2023/11/20 10:44* @Description: 资源类* 说明:2个线程使用if判断变量的值,没有问题,3个及3个以上线程会出现虚假唤醒的问题,需要注意!!!!!*/
public class ShareDataOne {private int number = 0;/*** 加1** @throws InterruptedException*/public synchronized void increment() throws InterruptedException {// 1、判断if (number != 0) {this.wait();}// 2、干活++number;System.out.println(Thread.currentThread().getName() + "\t" + number);// 3、通知this.notifyAll();}/*** 减1** @throws InterruptedException*/public synchronized void decrement() throws InterruptedException {// 1、判断if (number == 0) {this.wait();}// 2、干活--number;System.out.println(Thread.currentThread().getName() + "\t" + number);// 3、通知this.notifyAll();}
}

1.1.2、线程类ShareDataOneMainApp

/*** @Author : 一叶浮萍归大海* @Date: 2023/11/20 10:46* @Description:* 需求:两个线程,可以操作初始量为零的一个变量,实现一个线程对该变量加1,一个线程对该变量减1,交替来10轮* Java里边如何进行工程级别的多线程编写?*      1、多线程编程模板(套路上)*          1.1、线程 操作 资源类*          1.2、高内聚 低耦合**      2、多线程编程模板(套路下)*          2.1、判断*          2.2、干活*          2.3、通知**      3、防止虚假唤醒用while*/
public class ShareDataOneMainApp {public static void main(String[] args) {ShareDataOne sd = new ShareDataOne();new Thread(() -> {for (int i = 1; i <= 10; i++) {try {sd.increment();} catch (Exception e) {e.printStackTrace();}}}, "A").start();new Thread(() -> {for (int i = 1; i <= 10; i++) {try {sd.decrement();} catch (Exception e) {e.printStackTrace();}}}, "B").start();}}

1.1.3、结果

1.2、案例二(4个线程交替对变量执行+1、-1操作,来10轮) 

1.2.1、资源类ShareDataTwo

/*** @Author : 一叶浮萍归大海* @Date: 2023/11/20 10:44* @Description: 资源类* 说明:2个线程使用if判断变量的值,没有问题,3个及3个以上线程会出现虚假唤醒的问题,需要注意!!!!!* 解决方法:使用while做判断条件* 原理:中断和虚假唤醒是由可能产生的,所以要用loob循环,if只判断一次,while是只要唤醒就要拉回来再判断一次,if换成while即可解决虚假唤醒的问题*/
public class ShareDataTwo {private int number = 0;/*** 加1** @throws InterruptedException*/public synchronized void increment() throws InterruptedException {// 1、判断while (number != 0) {this.wait();}// 2、干活++number;System.out.println(Thread.currentThread().getName() + "\t" + number);// 3、通知this.notifyAll();}/*** 减1** @throws InterruptedException*/public synchronized void decrement() throws InterruptedException {// 1、判断while (number == 0) {this.wait();}// 2、干活--number;System.out.println(Thread.currentThread().getName() + "\t" + number);// 3、通知this.notifyAll();}
}

1.2.2、线程类

/*** @Author : 一叶浮萍归大海* @Date: 2023/11/20 11:19* @Description:* 需求:四个线程,可以操作初始量为零的一个变量,实现一个线程对该变量加1,一个线程对该变量减1,交替来10轮* Java里边如何进行工程级别的多线程编写?*      1、多线程编程模板(套路上)*          1.1、线程 操作 资源类*          1.2、高内聚 低耦合**      2、多线程编程模板(套路下)*          2.1、判断*          2.2、干活*          2.3、通知**      3、防止虚假唤醒用while*/
public class ShareDataTwoMainApp {public static void main(String[] args) {ShareDataTwo sdt = new ShareDataTwo();new Thread(() -> {for (int i = 1; i <= 10; i++) {try {sdt.increment();} catch (Exception e) {e.printStackTrace();}}}, "A").start();new Thread(() -> {for (int i = 1; i <= 10; i++) {try {sdt.decrement();} catch (Exception e) {e.printStackTrace();}}}, "B").start();new Thread(() -> {for (int i = 1; i <= 10; i++) {try {sdt.increment();} catch (Exception e) {e.printStackTrace();}}}, "C").start();new Thread(() -> {for (int i = 1; i <= 10; i++) {try {sdt.decrement();} catch (Exception e) {e.printStackTrace();}}}, "D").start();}}

1.2.3、结果

二、Condition实现

2.1、案例一(2个线程交替对变量执行+1、-1操作,来10轮)

2.1.1、资源类ShareDataThree

/*** @Author : 一叶浮萍归大海* @Date: 2023/11/20 11:40* @Description: 资源类* 说明:2个线程使用if判断变量的值,没有问题,3个及3个以上线程会出现虚假唤醒的问题,需要注意!!!!!* 解决方法:使用while做判断条件* 原理:中断和虚假唤醒是由可能产生的,所以要用loob循环,if只判断一次,while是只要唤醒就要拉回来再判断一次,if换成while即可解决虚假唤醒的问题*/
public class ShareDataThree {private Integer number = 0;private Lock lock = new ReentrantLock();private Condition condition = lock.newCondition();/*** 加1*/public void increment() {lock.lock();try {// 判断while (number != 0) {condition.await();}// 干活++number;System.out.println(Thread.currentThread().getName() + "\t" + number);// 通知condition.signalAll();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}/*** 加1*/public void decrement() {lock.lock();try {// 判断while (number == 0) {condition.await();}// 干活--number;System.out.println(Thread.currentThread().getName() + "\t" + number);// 通知condition.signalAll();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}}

2.1.2、线程类ShareDataThreeMainApp

/*** @Author : 一叶浮萍归大海* @Date: 2023/11/20 11:19* @Description:* 需求:两个线程,可以操作初始量为零的一个变量,实现一个线程对该变量加1,一个线程对该变量减1,交替来10轮* Java里边如何进行工程级别的多线程编写?*      1、多线程编程模板(套路上)*          1.1、线程 操作 资源类*          1.2、高内聚 低耦合**      2、多线程编程模板(套路下)*          2.1、判断*          2.2、干活*          2.3、通知**      3、防止虚假唤醒用while*/
public class ShareDataThreeMainApp {public static void main(String[] args) {ShareDataThree sdt = new ShareDataThree();new Thread(() -> {for (int i = 1; i <= 10; i++) {try {sdt.increment();} catch (Exception e) {e.printStackTrace();}}}, "A").start();new Thread(() -> {for (int i = 1; i <= 10; i++) {try {sdt.decrement();} catch (Exception e) {e.printStackTrace();}}}, "B").start();}}

 2.1.3、结果

2.2、案例二(4个线程交替对变量执行+1、-1操作,来10轮) 

2.2.1、资源类ShareDataThree

同2.1.1。

2.2.2、线程类

/*** @Author : 一叶浮萍归大海* @Date: 2023/11/20 11:19* @Description:* 需求:四个线程,可以操作初始量为零的一个变量,实现一个线程对该变量加1,一个线程对该变量减1,交替来10轮* Java里边如何进行工程级别的多线程编写?*      1、多线程编程模板(套路上)*          1.1、线程 操作 资源类*          1.2、高内聚 低耦合**      2、多线程编程模板(套路下)*          2.1、判断*          2.2、干活*          2.3、通知**      3、防止虚假唤醒用while*/
public class ShareDataFourMainApp {public static void main(String[] args) {ShareDataThree sdt = new ShareDataThree();new Thread(() -> {for (int i = 1; i <= 10; i++) {try {sdt.increment();} catch (Exception e) {e.printStackTrace();}}}, "A").start();new Thread(() -> {for (int i = 1; i <= 10; i++) {try {sdt.decrement();} catch (Exception e) {e.printStackTrace();}}}, "B").start();new Thread(() -> {for (int i = 1; i <= 10; i++) {try {sdt.increment();} catch (Exception e) {e.printStackTrace();}}}, "C").start();new Thread(() -> {for (int i = 1; i <= 10; i++) {try {sdt.decrement();} catch (Exception e) {e.printStackTrace();}}}, "D").start();}}

2.2.3、结果

三、线程间定制化通信

3.1、资源类ShareDataFive

/*** @Author : 一叶浮萍归大海* @Date: 2023/11/20 12:12* @Description: 资源类* 说明:2个线程使用if判断变量的值,没有问题,3个及3个以上线程会出现虚假唤醒的问题,需要注意!!!!!* 解决方法:使用while做判断条件* 原理:中断和虚假唤醒是由可能产生的,所以要用loob循环,if只判断一次,while是只要唤醒就要拉回来再判断一次,if换成while即可解决虚假唤醒的问题*/
public class ShareDataFive {private Integer number = 1;private Lock lock = new ReentrantLock();private Condition condition1 = lock.newCondition();private Condition condition2 = lock.newCondition();private Condition condition3 = lock.newCondition();public void print5(int totalLoopNumber) {lock.lock();try {// 判断while (number != 1) {condition1.await();}// 干活for (int i = 1; i <= totalLoopNumber; i++) {System.out.println("【当前线程】:" + Thread.currentThread().getName() + ",【当前i的值】:" + i + ",【totalLoopNumber】:" + totalLoopNumber);}// 通知number = 2;condition2.signal();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}public void print10(int totalLoopNumber) {lock.lock();try {// 判断while (number != 2) {condition2.await();}// 干活for (int i = 1; i <= totalLoopNumber; i++) {System.out.println("【当前线程】:" + Thread.currentThread().getName() + ",【当前i的值】:" + i + ",【totalLoopNumber】:" + totalLoopNumber);}// 通知number = 3;condition3.signal();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}public void print15(int totalLoopNumber) {lock.lock();try {// 判断while (number != 3) {condition3.await();}// 干活for (int i = 1; i <= totalLoopNumber; i++) {System.out.println("【当前线程】:" + Thread.currentThread().getName() + ",【当前i的值】:" + i + ",【totalLoopNumber】:" + totalLoopNumber);}// 通知number = 1;condition1.signal();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}
}

3.2、线程类

/*** @Author : 一叶浮萍归大海* @Date: 2023/11/20 12:22* @Description: 需求:多个线程之间按顺序调用,实现AA>BB>CC,三个线程启动,* 要求:* AA打印5次,BB打印10次,CC打印15次* 接着,AA打印5次,BB打印10次,CC打印15次* ...* 来10轮*/
public class ShareDataFiveMainApp {public static void main(String[] args) {ShareDataFive sdf = new ShareDataFive();new Thread(() -> {for (int i = 1; i <= 10; i++) {sdf.print5(5);}}, "AA").start();new Thread(() -> {for (int i = 1; i <= 10; i++) {sdf.print10(10);}}, "BB").start();new Thread(() -> {for (int i = 1; i <= 10; i++) {sdf.print15(15);}}, "CC").start();}}

3.3、结果

 

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

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

相关文章

Linux 信号

目录 1.什么是信号 2.信号的产生 处理信号的常见方式&#xff1a; 如何理解这些组合键是如何变成信号的&#xff1f; 信号发送本质​编辑 信号的种类 ​编辑 3.信号处理常见方式概览 4.产生信号 5.信号其他相关常见概念 ​编辑 6.捕捉信号 signal函数&#xff1a; …

【Go语言实战】(26) 分布式搜索引擎

Tangseng 基于Go语言的搜索引擎 github地址&#xff1a;https://github.com/CocaineCong/tangseng 详细介绍地址&#xff1a;https://cocainecong.github.io/tangseng 这两周我也抽空录成视频发到B站的&#xff5e; 本来应该10月份就要发了&#xff0c;结果一鸽就鸽到现在hh…

Conditional GAN

Text-to-Image 对于根据文字生成图像的问题&#xff0c;传统的做法就是训练一个NN&#xff0c;然后输入一段文字&#xff0c;输出对应一个图片&#xff0c;输出图片与目标图片越接近越好。存在的问题就是&#xff0c;比如火车对应的图片有很多张&#xff0c;如果用传统的NN来训…

shell编脚本概述和变量解释

shell的基本概述和规范 shell面向的对象 面向过程语言 &#xff08;开发的时候&#xff0c;需要一步一步的执行&#xff09; 做一件事情&#xff0c;排出个步骤&#xff0c;第一步干什么&#xff0c;第二步干什么&#xff0c;如果出现情况A&#xff0c;做什么处理&#xff0…

澳洲猫罐头如何?我亲自喂养过的优质猫罐头分享

猫罐头要符合三点&#xff1a;营养配方完整均衡、原料新鲜优质、生产工艺科学可靠。只有具备这些特点&#xff0c;才是品质上乘的猫罐头。 猫罐头的三个要素&#xff0c;一个都不能少。配方不均衡&#xff0c;营养就不足&#xff1b;原料不新鲜&#xff0c;生产出来的猫罐头就…

NX二次开发UF_CAM_ask_lower_limit_plane_data 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;里海NX二次开发3000例专栏 UF_CAM_ask_lower_limit_plane_data Defined in: uf_cam_planes.h int UF_CAM_ask_lower_limit_plane_data(tag_t object_tag, double origin [ 3 ] , double normal [ 3 ] ) overview 概述 Query …

鸿蒙开发|鸿蒙系统项目开发前的准备工作

文章目录 鸿蒙项目开发的基本流程介绍鸿蒙项目开发和其他项目有什么不同成为华为开发者-注册和实名认证1.登录官方网站 鸿蒙项目开发的基本流程介绍 直接上图&#xff0c;简单易懂&#xff01; 整个项目的开发通过4个模块进行&#xff1a;开发准备、开发应用、运行调试测试和发…

关于使用宝塔页面Nginx的一些注意事项:Nginx不生效情况,以及解决方案

判断Nginx是否正常运行 使用宝塔页面保存Nginx配置后&#xff0c;有的时候不生效&#xff0c;这就说明Nginx没有正常运行 可以通过以下几种方式排查 通过宝塔 如果能够打开负载状态&#xff0c;说明Nginx运行正常 如果打不开&#xff0c;说明肯定是配置文件或者什么导致ngi…

NameServer源码解析

1 模块入口代码的功能 本节介绍入口代码的功能&#xff0c;阅读源码的时候&#xff0c;很多人喜欢根据执行逻辑&#xff0c;先从入口代码看起。NameServer部分入口代码主要完成命令行参数解析&#xff0c;初始化Controller的功能。 1.1 入口函数 首先看一下NameServer的源码目…

代码随想录算法训练营第五十九天丨 单调栈02

503.下一个更大元素II 思路 做本题之前建议先做739. 每日温度 (opens new window)和 496.下一个更大元素 I (opens new window)。 这道题和739. 每日温度 (opens new window)也几乎如出一辙。 不过&#xff0c;本题要循环数组了。 关于单调栈的讲解我在题解739. 每日温度 …

el-table 对循环产生的空白列赋默认值

1. el-table 空白列赋值 对el-table中未传数据存在空白的列赋默认值0。使用el-table 提供的插槽 slot-scope&#xff1a;{{ row || ‘0’ }} 原数据&#xff1a; <el-table-column label"集镇" :propcity ><template slot-scope"{row}">{{…

Vue实现表单效验

第一步&#xff1a;首先给form表单绑定一个rules属性 和 ref属性 <el-form :model"addFroms" label-position"right" :rules"rules" ref"ruleFormRef" label-width"100px"></el-form> 第二步&#xff1a;获取表…

TCC简介

TCC TCC&#xff08;Try-Confirm/Cancel&#xff09;是一种分布式事务处理模型&#xff0c;旨在解决分布式系统中的事务一致性问题。 三阶段 Try阶段&#xff1a; 在这个阶段&#xff0c;业务参与者尝试执行事务&#xff0c;并执行相应的业务逻辑。该阶段用于检查事务执行的…

007 OpenCV霍夫变换

目录 一、环境 二、霍夫变换原理 三、代码 一、环境 本文使用环境为&#xff1a; Windows10Python 3.9.17opencv-python 4.8.0.74 二、霍夫变换原理 OpenCV中的霍夫变换是一种用于检测图像中直线和圆的算法。它基于图像中像素的分布情况&#xff0c;通过统计像素点之间的…

2024年山东省职业院校技能大赛中职组“网络安全”赛项竞赛试题-C

2024年山东省职业院校技能大赛中职组 “网络安全”赛项竞赛试题-C 一、竞赛时间 总计&#xff1a;360分钟 二、竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 A、B模块 A-1 登录安全加固 180分钟 200分 A-2 本地安全策略设置 A-3 流量完整性保护 A-4 …

基于springboot实现智能热度分析和自媒体推送平台系统项目【项目源码】计算机毕业设计

基于springboot实现智能热度分析和自媒体推送平台演示 系统开发平台 在该自媒体分享网站中&#xff0c;Eclipse能给用户提供更多的方便&#xff0c;其特点一是方便学习&#xff0c;方便快捷&#xff1b;二是有非常大的信息储存量&#xff0c;主要功能是用在对数据库中查询和编…

纯CSS实现炫酷文本时钟

如图所示这是一个纯本文时钟效果,和传统的时钟不一样,没有表盘,也没有完整到每一分钟的数字表示当前时刻。 在这个时钟中,当前时间通过文本显示,显示的文本时间误差为+/- 4分钟,以明亮的颜色突出显示当前时间,而其余字母则较暗。 实际上这是一个实现很复杂的时钟,因为…

EOCR电机保护器的日常维护与保养技巧

EOCR是由施耐德韩国公司生产的电动机保护系列产品&#xff0c;由电子器件和互感器等部件组成&#xff0c;在正常状态下使用都有各自的机械寿命和电气寿命,若操作不当或异常条件下会加速电器元件的老化&#xff0c;缩短保护器的使用寿命&#xff0c;所以电机保护器的正确使用和正…

css 实现文字流光效果

经过调研发现大多滑块验证码中&#xff0c;有一些文字流光效果&#xff0c;因此在这里简单实现一下。 实现主要利用background 渐变背景以及backgorund-clip:text实现。具体代码如下 css部分 .slide {width: 300px;height: 40px;border: 1px solid #ccc;border-radius: 8px;…