系列五、线程间通信

一、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.rhkb.cn/news/198671.html

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

相关文章

企业微信获取第三方应用凭证

上一篇介绍了如何配置通用开发参数及通过url回调验证&#xff0c; 本篇将通过服务商后台配置关联小程序应用配置和获取第三方凭证及如何配置企业可信IP。 当然上篇配置的回调设置也不会白费&#xff0c;在下方的指令和数据回调会用到。 第三方应用开发流程 官方企业微信第三方…

微服务学习|Nacos配置管理:统一配置管理、配置热更新、配置共享、搭建Nacos集群

统一配置管理 在微服务当中&#xff0c;提供一个配置中心来将一些配置提取出来&#xff0c;进行统一的使用&#xff0c;Nacos既可以充当注册中心&#xff0c;也提供配置中心的功能。 1.在Nacos中添加配置文件 在Nacos控制台&#xff0c;我们可以在配置管理中&#xff0c;添加…

servlet乱码问题

问题&#xff1a;中文乱码 解决&#xff1a;加框的部分

「Verilog学习笔记」ROM的简单实现

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 分析 要实现ROM&#xff0c;首先要声明数据的存储空间&#xff0c;例如&#xff1a;[3:0] rom [7:0]&#xff1b;变量名称rom之前的[3:0]表示每个数据具有多少位&#xff0…

云原生微服务-理论篇

文章目录 分布式应用的需求分布式架构治理模式演进ESB 是什么&#xff1f;微服务架构 MSA微服务实践细节微服务治理框架sidercar 什么是service mesh&#xff1f;康威定律微服务的扩展性什么是MSA 架构&#xff1f;中台战略和微服务微服务总体架构组件微服务网关服务发现与路由…

成都优优聚美团代运营:塑造卓越优势,引领电商新时代

在当今这个数字化时代&#xff0c;美团作为中国最大的本地生活服务平台之一&#xff0c;正在为消费者和商家搭建一个无缝链接的桥梁。而在成都&#xff0c;有一家名为优优聚美团代运营的公司&#xff0c;他们凭借着专业的技能和高效的服务&#xff0c;成为了美团平台上的佼佼者…

Spring IOC - Bean的生命周期之依赖注入

在Spring启动流程中&#xff0c;创建的factoryBean是DefaultListableBeanFactory&#xff0c;其类图如下所示&#xff1a; 可以看到其直接父类是AbstractAutoireCapableBeanFactory&#xff0c;他主要负责完成Bean的自动装配和创建工作。 具体来说&#xff0c;AbstractAutowire…

MySQL 之多版本并发控制 MVCC

MySQL 之多版本并发控制 MVCC 1、MVCC 中的两种读取方式1.1、快照读1.2、当前读 2、MVCC实现原理之 ReadView2.1、隐藏字段2.2、ReadView2.3、读已提交和可重复读隔离级别下&#xff0c;产生 ReadView 时机的区别 3、MVCC 解决幻读4、总结 MVCC&#xff08;多版本并发控制&…

【C++】pow函数实现的伽马变换详解和示例

本文通过原理和示例对伽马变换进行详解&#xff0c;并通过改变变换系数展示不同的效果&#xff0c;以帮助大家理解和使用。 原理 伽马变换是一种用于图像增强的技术&#xff0c;它可以用来提高或降低图像的对比度&#xff0c;常用于医学图像处理和计算机视觉等领域。伽马变换…

node 第十八天 中间件express-session实现会话密钥

express-session 文档 express-session 一个简单的express会话中间件 使用场景 在一个系统中&#xff0c; 需要维持一个临时的与登录态无关的会话密钥 比如登录系统后&#xff0c; 请求某一个接口&#xff0c; 接口的行为与登录态无关&#xff0c; 也就是说任何人对接口的访问…

steam搬砖项目2023年现状分析,到底还能不能做?

关于CSGO游戏搬砖项目的5大认知误区 当前的steam搬砖项目市场正变得混乱不堪。你对该项目的了解程度决定了你是否能在这个生态系统中获得收益。 假设你有100万资金&#xff0c;想要全部投入搬砖事业&#xff0c;但对项目一无所知&#xff0c;只看中收益。即使你有充足的资金&a…

Debian系列的Linux发行版上部署wvp

Debian系列的Linux发行版上部署wvp 环境搭建1.Debian系列的Linux发行版上安装nginx2.安装mysql设置mysql密码修改权限sudo mysql ERROR 1045 (28000): Access denied for user root@localhost (using password: NO)配置相关navicat 连接不上 报错 10061navicat 连接报错 1130 -…

springcloudalibaba-3

一、Nacos Config入门 1. 搭建nacos环境【使用现有的nacos环境即可】 使用之前的即可 2. 在微服务中引入nacos的依赖 <!-- nacos配置依赖 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-…

最新版微信如何打开青少年模式?

最新版微信如何打开青少年模式&#xff1f; 1、将手机微信升级到最新版&#xff0c;并打开后点击底部我的进入&#xff1b; 2、在我的内&#xff0c;找到并点击设置进入&#xff1b; 3、在设置内找到青少年模式&#xff0c;并点击进入开启微信青少年模式&#xff1b; 原文来源…

无菌药品生产(A级区域)--气流流型测试可视化烟雾试验详细介绍

技术背景 无菌药品是指法定药品标准中列有无菌检测项目的制剂和原料药&#xff0c;包括注射剂、眼用制剂、无菌软膏剂、无菌混悬剂等。目前工程中&#xff0c;以注射剂产品为主的厂房占据了很大的比重。 无菌药品生产质量风险管理中&#xff0c;人员及其活动被视为重大的污染…

如何进行手动脱壳

脱壳的目的就是找到被隐藏起来的OEP&#xff08;入口点&#xff09; 这里我一共总结了三种方法&#xff0c;都是些自己的理解希望对你们有用 单步跟踪法 一个程序加了壳后&#xff0c;我们需要找到真正的OEP入口点&#xff0c;先运行&#xff0c;找到假的OEP入口点后&#x…

计算机网络八股文

计算机网络八股文 第一章 计算机网络基础 1.1 OSI 七层参考模型及各自功能 七层参考模式是一个抽象的模型体&#xff0c;不仅包括一系列抽象的术语或概念&#xff0c;也包括具体的协议。 &#xff08;物、数、网、传、会、表、应&#xff09; 物理层&#xff1a;主要定义物…

各类语言真实性能比较列表

这篇文章是我所做或将要做的所有真实世界性能比较的索引。如果你对想要看到的其他真实世界案例有建议&#xff0c;请在评论中添加。 用例 1 — JWT 验证 & MySQL 查询 该用例包括&#xff1a; 从授权头部获取 JWT验证 JWT 并从声明中获取电子邮件使用电子邮件执行 MySQL…

linux上交叉编译qt库

linux上交叉编译qt库 Qt程序从X86平台Linux移植到ARM平台Linux需要做什么 1.在ubuntu上使用qt的源码交叉编译出Qt库 2.将编译好的库拷贝到开发板上并设置相应的环境变量&#xff08;库路径啥的&#xff09; 前两步一劳永逸&#xff0c;做一次就行 3.X86上写好程序代码&…

【开源】基于Vue.js的智能教学资源库系统

项目编号&#xff1a; S 050 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S050&#xff0c;文末获取源码。} 项目编号&#xff1a;S050&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 课程档案模块2.3 课…