java干货 线程间通信
文章目录
- 一、线程间通信
- 1.1 为什么要处理线程间通信?
- 1.2 什么是等待唤醒机制?
- 二、等待唤醒机制使用
- 2.1 等待唤醒机制用到的方法
- 2.1.1 wait
- 2.1.2 notify
- 2.2 线程通信代码实践
- 2.2.1 重要说明
- 2.2.2 代码
一、线程间通信
1.1 为什么要处理线程间通信?
- 在默认情况下,cpu是默认切换线程来执行的,当我们需要多个线程共同来完成一个任务,希望他们按照一定的规律执行,那么就需要他们进行通信协调,以达到我们的目的
- 其次,对于共享变量的访问,我们通常加上synchronized,存在锁的竞争,我们也可以使用等待唤醒机制,协调线程对变量的访问,保证数据的一致性
1.2 什么是等待唤醒机制?
说到线程,我们常提到线程之间的竞争,如多线程下锁的竞争。好比在公司里你和同事在晋升时的竞争,但是多数情况下,还是你们合作共同完成一些任务。也就是一个线程进行了一定操作后,进入等待状态(waiting),等待其他线程完成任务后将他唤醒(notify)。还有就是当需要等待多个线程时,可以使用notifyAll(),将等待中的线程全部唤醒
二、等待唤醒机制使用
2.1 等待唤醒机制用到的方法
2.1.1 wait
- wait() 使当前线程进入等待状态,直到被其他线程使用 notify() 或 notifyAll() 唤醒,无限期等待,直到被唤醒。使用场景: 当线程需要等待某个条件变化时使用,无需考虑超时。
public final void wait() throws InterruptedException {wait(0L);}
- wait(long timeoutMillis),本质上调用的还是这个native 方法
public final native void wait(long timeoutMillis);
- wait(long timeoutMillis, int nanos) 可以被其他线程调用 notify() 或 notifyAll() 来唤醒,也可以在超时后自动唤醒。
public final void wait(long timeoutMillis, int nanos) throws InterruptedException {if (timeoutMillis < 0) {throw new IllegalArgumentException("timeoutMillis value is negative");}if (nanos < 0 || nanos > 999999) {throw new IllegalArgumentException("nanosecond timeout value out of range");}if (nanos > 0 && timeoutMillis < Long.MAX_VALUE) {timeoutMillis++;}wait(timeoutMillis);}
2.1.2 notify
- notify 是 Object 类的方法,任何对象都可以调用它。notify 方法用于唤醒一个在该对象的监视器上等待的线程。
- notify() 适用于只需要唤醒一个等待线程的情况,如果有多个线程等待,随机唤醒一个
public final native void notify();
- notifyAll() 唤醒对象监视器上所有等待的线程
public final native void notifyAll();
2.2 线程通信代码实践
2.2.1 重要说明
- 等待和通知唤醒必须放在同步代码块
是为了确保线程在进入等待状态和被唤醒时,对共享资源的访问是受控和一致的。这种机制保证了线程间的协调和通信是安全的,避免了竞争条件和数据不一致的问题。同步块保证了在任意时刻只有一个线程可以执行同步代码块中的代码,从而确保了线程间通信的正确性和一致性。
举个例子,张三、李四、王五共同完成一个任务,要求张三先做,再到李四、最后王五,那么三个人就是三个线程,一个人在做任务的时候,其他人是不能动的。张三做完了,把执行权交给李四,并通知李四,李四执行完了,通知王五。 - 调用wait,那么当前线程也就释放了锁,即交出执行权,线程进入WAITING 状态
- wait 和 notify 必须由同一个锁对象调用。一个锁对象可以唤醒 由同一个锁对象调用wait 后的线程
- wait 和 notify 是属于 Object 类的,锁对象可以是任意对象,其他类默认都是继承了Object类的
2.2.2 代码
- 客人来了,张三洗菜、李四切菜、王五炒菜
public class Demo10 {private static final Object lock = new Object(); // 锁对象private static boolean vegetablesWashed = false; // 是否已经洗菜完成private static boolean vegetablesCut = false; // 是否已经切菜完成public static void main(String[] args) {new Thread(new Runnable() {@Overridepublic void run() {synchronized (lock){while (!vegetablesCut){try {System.out.println("王五等待李四切菜...");lock.wait(); // 李四没有切完菜,继续等} catch (InterruptedException e) {Thread.currentThread().interrupt();}}System.out.println("》》》》王五开始炒菜《《《《");try {Thread.sleep(1200); // 模拟炒菜过程System.out.println("》》》王五炒菜完成《《《");lock.notifyAll();} catch (InterruptedException e) {e.printStackTrace();}}}},"王五线程").start();new Thread(new Runnable() {@Overridepublic void run() {synchronized (lock){while (!vegetablesWashed){try {System.out.println("李四等待张三洗菜...");lock.wait(); // 张三没有切完菜,继续等} catch (InterruptedException e) {Thread.currentThread().interrupt();}}System.out.println("======李四开始切菜======");try {Thread.sleep(1600); // 模拟切菜过程vegetablesCut = true;System.out.println("===李四切完菜了===");lock.notifyAll(); // 通知王五炒菜} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}},"李四线程").start();new Thread(new Runnable() {@Overridepublic void run() {synchronized (lock){System.out.println("----张三开始洗菜----");try {Thread.sleep(1500); // 模拟洗菜过程vegetablesWashed = true;System.out.println("---张三洗完菜了---");lock.notifyAll();} catch (InterruptedException e) {e.printStackTrace();}}}},"张三线程").start();}
}
王五等待李四切菜...
李四等待张三洗菜...
----张三开始洗菜----
---张三洗完菜了---
王五等待李四切菜...
======李四开始切菜======
===李四切完菜了===
》》》》王五开始炒菜《《《《
》》》王五炒菜完成《《《
分析:上一个人未完成,那么下一个人就继续等待。一个人完成了,要通知所有人,每个人根据自己的顺序,接到通知后,看是否要做,不做任务就继续等待。保证了张三先洗完菜,李四再开始切菜,李四切完菜,王五再炒菜的顺序
相关文章:
java干货 线程间通信
文章目录 一、线程间通信1.1 为什么要处理线程间通信?1.2 什么是等待唤醒机制? 二、等待唤醒机制使用2.1 等待唤醒机制用到的方法2.1.1 wait2.1.2 notify 2.2 线程通信代码实践2.2.1 重要说明2.2.2 代码 一、线程间通信 1.1 为什么要处理线程间通信&…...

【人机交互 复习】第6章 交互式系统的设计
一、设计框架 1.在建立了一组需求之后,设计即将开始,建议采取自上面下的方式,首先把重点放在大的方面,生成低保真且不包含具体细节的方案,一般通过写剧本来确定交互设计模式与逻辑。 2.设计框架: 先站在一个…...

1-函数极限与连续
1 2 平方项没有考虑到(其正负)...

【C++题解】1670 - 象棋大赛
问题:1670 - 象棋大赛 类型:分支问题 题目描述: 市里要组织象棋大赛,年龄在 8∼30 周岁之间的选手可以报名参赛。为了公平起见,大赛组委会将选手们分了青年组、少年组和儿童组,大赛组委会规定:…...
Samba:用于高效无限上下文语言建模的简单混合状态空间模型
Samba: Simple Hybrid State Space Models for Efficient Unlimited Context Language Modeling 📜 文献卡 Samba: Simple Hybrid State Space Models for Efficient Unlimited Context Language Modeling作者: Liliang Ren; Yang Liu; Yadong Lu; Yelong Shen; …...
通俗易懂的ChatGPT原理简介
一、引言 随着人工智能的发展,聊天机器人已经成为我们生活中的常见工具。而在众多聊天机器人中,ChatGPT 无疑是最受关注的一个。ChatGPT 是由 OpenAI 开发的一种基于生成式预训练模型(GPT)的大型语言模型。本文将通俗易懂地介绍 …...

你认为 AI 作图程序「MidJourney」有哪些比较好用的关键词?
玩了一段时间的MidJourney,打算把这个回答做成资源帖。也欢迎在评论区补充讨论。 MidJourney的极简指南 快速上手 装discord,或者直接打开网址 https://discord.gg/midjourney 注册用户。进入Midjourney的官方服务器后,在左侧栏找一个newb…...
9.2JavaEE——JDBCTemplate的常用方法(一)excute()方法
execute()方法用于执行SQL语句,其语法格式如下: jdTemplate.execute("SQL 语句");下面以创建数据表的SQL语句为例,来演示excute()方法的使用,具体步骤如下。 1、创建数据库 在MySQL中,创建一个名为spring的…...
正向代理和反向代理的区别
正向代理和反向代理的主要区别在于代理服务器所服务的对象不同。 正向代理(Forward Proxy):正向代理的客户端是内部网络的用户。当内部网络的用户想要访问外部网络(例如互联网)时,可以通过正向代理服务器来…...

express入门03增删改查
目录 1 搭建服务器2 静态文件托管3 引入bootstrap4 引入jquery5 编写后端接口5.1 添加列表查询方法5.2 添加路由5.3 添加数据表格 总结 我们前两篇介绍了如何利用express搭建服务器,如何实现静态资源托管。那利用这两篇的知识点,我们就可以实现一个小功能…...

【usb设备端口异常】——使用ls /dev/video*查看设备号时出现报错:ls:无法访问‘/dev/video*‘: 没有那个文件或目录
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、ls:无法访问/dev/video*: 没有那个文件或目录1. 问题描述2. 原因分析3. 解决方法 总结 前言 一、ls:无法访问’/dev/video*: 没有那个文件或目录 使用的这…...

Java实现异步开发的方式
1)、继承 Thread 2)、实现 Runnable 接口 3)、实现 Callable 接口 FutureTask (可以拿到返回结果,可以处理异常) 4)、使用线程池 区别:1、2)不能得到返回值 …...

小知识点快速总结:Batch Normalization Layer(BN层)的作用
本系列文章只做简要总结,不详细说明原理和公式。 目录 1. 参考文章2. 主要作用3. 具体分析3.1 正则化,降低过拟合3.2 提高模型收敛速度,加速训练3.3 减少梯度爆炸或者梯度消失的情况 4. 补充4.1 BN层做的是标准化不是归一化4.2 BN层的公式4.…...

【SpringCloud】负载均衡(Spring Cloud LoadBalancer)
负载均衡 当服务流量增大时,通常会采用增加机器的方式进行扩容。负载均衡就是用来在多个机器或者其他资源中,按照一定的规则合理分配负载。其中的实现可以分成客户端负载均衡和服务端负载均衡。 服务端负载均衡 在服务端进行负载均衡的算法分配。 比…...
三生随记——输入法之谜
在深夜的电脑前,李浩专心致志地敲打着键盘,为他的小说写下最后一章。然而,随着他不断输入文字,他渐渐察觉到一丝不对劲。每次他尝试输入特定的词汇,输入法都会自动跳转到一些与主题毫不相关的句子,甚至有些…...
【名词解释】Unity中的3D物理系统:刚体
Unity中的3D物理系统是用于模拟现实世界中物体的运动和相互作用的一套工具和组件。刚体(Rigidbody)是Unity 3D物理系统中的一个核心组件,它允许游戏对象(GameObject)受到重力和外力的影响,并参与碰撞检测。…...
icon转svg处理
一般情况下,图标我们可以找UI或者去iconfont.cn获得一个svg格式的文件。然后再IDE中以文本的方式打开,然后格式化,就可以看到代码。代码中一般是最外层一个svg标签,里面是一个或者多个path。这个时候,我们使用h方法来实…...

已成功见刊检索的国际学术会议论文海报展示(2)
【先投稿先送审】第四届计算机、物联网与控制工程国际学术会议(CITCE 2024) 大会官网:www.citce.org 时间地点:2024年11月1-3日,中国-武汉 收录检索:EI Compendex,Scopus 主办单位:四川师范…...

EasyCVR/EasyDSS无人机直播技术助力野生动物监测
近日有新闻报道,一名挖掘机师傅在清理河道时,意外挖出一只稀有的扬子鳄,挖机师傅小心翼翼地将其放在一边,扬子鳄也顺势游回一旁的河道中。 随着人类对自然环境的不断探索和开发,野生动物及其栖息地的保护显得愈发重要。…...

AI视频教程下载-ChatGPT 生产力 + 时间管理
ChatGPT Productivity Time Management. ChatGPT Productivity ChatGPT 显著提升生产力 不寻常的时间管理技巧。ChatGPT 工作,Chat GPT 自动化,ChatGPT 2023! 对关于ChatGPT的讨论感到好奇,想知道如何利用它为自己带来好处吗&a…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...

LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...

通过MicroSip配置自己的freeswitch服务器进行调试记录
之前用docker安装的freeswitch的,启动是正常的, 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...

Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...

GAN模式奔溃的探讨论文综述(一)
简介 简介:今天带来一篇关于GAN的,对于模式奔溃的一个探讨的一个问题,帮助大家更好的解决训练中遇到的一个难题。 论文题目:An in-depth review and analysis of mode collapse in GAN 期刊:Machine Learning 链接:...

深入解析光敏传感技术:嵌入式仿真平台如何重塑电子工程教学
一、光敏传感技术的物理本质与系统级实现挑战 光敏电阻作为经典的光电传感器件,其工作原理根植于半导体材料的光电导效应。当入射光子能量超过材料带隙宽度时,价带电子受激发跃迁至导带,形成电子-空穴对,导致材料电导率显著提升。…...