系列五、线程间通信

一、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,一经查实,立即删除!

相关文章

【微软技术栈】C#.NET 内置数值转换

本文内容 隐式数值转换显式数值转换 C# 提供了一组整型和浮点数值类型。 任何两种数值类型之间都可以进行隐式或显式转换。 必须使用强制转换表达式来执行显式转换。 1、隐式数值转换 下表显示内置数值类型之间的预定义隐式转换&#xff1a; From到sbyteshort、int、long、…

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;开发准备、开发应用、运行调试测试和发…

一道简单的无穷级数题目

求级数 ∑ n 1 ∞ n x n \sum _{n1} ^ {\infty} n x^n n1∑∞​nxn 解析&#xff1a; 设 s ∑ n 1 ∞ n x n s \sum _{n1} ^ {\infty} n x^n sn1∑∞​nxn s 1 ∑ n 1 ∞ n x n − 1 s_1 \sum _{n1} ^ {\infty} n x^{n-1} s1​n1∑∞​nxn−1 则 s s 1 x s s_1…

关于使用宝塔页面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. 每日温度 …

Django学习日志06

模板层之过滤器 # 过滤器给我们提供的有六十多个&#xff0c;但是我们只需要掌握10个以内即可 # 过滤器名称就是函数名 语法&#xff1a; {{ obj|filter__name:param }} 变量名字|过滤器名称&#xff1a;变量 模板层之标签 # {% if %}会对一个变量求值&#xff0c;如果…

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}">{{…

milvus数据库搜索

一、向量相似度搜索 在Milvus中进行向量相似度搜索时&#xff0c;会计算查询向量和集合中具有指定相似性度量的向量之间的距离&#xff0c;并返回最相似的结果。通过指定一个布尔表达式来过滤标量字段或主键字段&#xff0c;您可以执行混合搜索。 1.加载集合 执行操作的前提是…

【Leetcode合集】13. 罗马数字转整数

13. 罗马数字转整数 13. 罗马数字转整数 代码仓库地址&#xff1a; https://github.com/slience-me/Leetcode 个人博客 &#xff1a;https://slienceme.xyz 罗马数字包含以下七种字符: I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 字符…

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;通过统计像素点之间的…