当前位置: 首页 > news >正文

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 为什么要处理线程间通信&#xff1f;1.2 什么是等待唤醒机制&#xff1f; 二、等待唤醒机制使用2.1 等待唤醒机制用到的方法2.1.1 wait2.1.2 notify 2.2 线程通信代码实践2.2.1 重要说明2.2.2 代码 一、线程间通信 1.1 为什么要处理线程间通信&…...

【人机交互 复习】第6章 交互式系统的设计

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

1-函数极限与连续

1 2 平方项没有考虑到&#xff08;其正负&#xff09;...

【C++题解】1670 - 象棋大赛

问题&#xff1a;1670 - 象棋大赛 类型&#xff1a;分支问题 题目描述&#xff1a; 市里要组织象棋大赛&#xff0c;年龄在 8∼30 周岁之间的选手可以报名参赛。为了公平起见&#xff0c;大赛组委会将选手们分了青年组、少年组和儿童组&#xff0c;大赛组委会规定&#xff1a…...

Samba:用于高效无限上下文语言建模的简单混合状态空间模型

Samba: Simple Hybrid State Space Models for Efficient Unlimited Context Language Modeling &#x1f4dc; 文献卡 Samba: Simple Hybrid State Space Models for Efficient Unlimited Context Language Modeling作者: Liliang Ren; Yang Liu; Yadong Lu; Yelong Shen; …...

通俗易懂的ChatGPT原理简介

一、引言 随着人工智能的发展&#xff0c;聊天机器人已经成为我们生活中的常见工具。而在众多聊天机器人中&#xff0c;ChatGPT 无疑是最受关注的一个。ChatGPT 是由 OpenAI 开发的一种基于生成式预训练模型&#xff08;GPT&#xff09;的大型语言模型。本文将通俗易懂地介绍 …...

你认为 AI 作图程序「MidJourney」有哪些比较好用的关键词?

玩了一段时间的MidJourney&#xff0c;打算把这个回答做成资源帖。也欢迎在评论区补充讨论。 MidJourney的极简指南 快速上手 装discord&#xff0c;或者直接打开网址 https://discord.gg/midjourney 注册用户。进入Midjourney的官方服务器后&#xff0c;在左侧栏找一个newb…...

9.2JavaEE——JDBCTemplate的常用方法(一)excute()方法

execute()方法用于执行SQL语句&#xff0c;其语法格式如下&#xff1a; jdTemplate.execute("SQL 语句");下面以创建数据表的SQL语句为例&#xff0c;来演示excute()方法的使用&#xff0c;具体步骤如下。 1、创建数据库 在MySQL中&#xff0c;创建一个名为spring的…...

正向代理和反向代理的区别

正向代理和反向代理的主要区别在于代理服务器所服务的对象不同。 正向代理&#xff08;Forward Proxy&#xff09;&#xff1a;正向代理的客户端是内部网络的用户。当内部网络的用户想要访问外部网络&#xff08;例如互联网&#xff09;时&#xff0c;可以通过正向代理服务器来…...

express入门03增删改查

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

【usb设备端口异常】——使用ls /dev/video*查看设备号时出现报错:ls:无法访问‘/dev/video*‘: 没有那个文件或目录

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、ls:无法访问/dev/video*: 没有那个文件或目录1. 问题描述2. 原因分析3. 解决方法 总结 前言 一、ls:无法访问’/dev/video*: 没有那个文件或目录 使用的这…...

Java实现异步开发的方式

1&#xff09;、继承 Thread 2&#xff09;、实现 Runnable 接口 3&#xff09;、实现 Callable 接口 FutureTask &#xff08;可以拿到返回结果&#xff0c;可以处理异常&#xff09; 4&#xff09;、使用线程池 区别&#xff1a;1、2&#xff09;不能得到返回值 …...

小知识点快速总结:Batch Normalization Layer(BN层)的作用

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

【SpringCloud】负载均衡(Spring Cloud LoadBalancer)

负载均衡 当服务流量增大时&#xff0c;通常会采用增加机器的方式进行扩容。负载均衡就是用来在多个机器或者其他资源中&#xff0c;按照一定的规则合理分配负载。其中的实现可以分成客户端负载均衡和服务端负载均衡。 服务端负载均衡 在服务端进行负载均衡的算法分配。 比…...

三生随记——输入法之谜

在深夜的电脑前&#xff0c;李浩专心致志地敲打着键盘&#xff0c;为他的小说写下最后一章。然而&#xff0c;随着他不断输入文字&#xff0c;他渐渐察觉到一丝不对劲。每次他尝试输入特定的词汇&#xff0c;输入法都会自动跳转到一些与主题毫不相关的句子&#xff0c;甚至有些…...

【名词解释】Unity中的3D物理系统:刚体

Unity中的3D物理系统是用于模拟现实世界中物体的运动和相互作用的一套工具和组件。刚体&#xff08;Rigidbody&#xff09;是Unity 3D物理系统中的一个核心组件&#xff0c;它允许游戏对象&#xff08;GameObject&#xff09;受到重力和外力的影响&#xff0c;并参与碰撞检测。…...

icon转svg处理

一般情况下&#xff0c;图标我们可以找UI或者去iconfont.cn获得一个svg格式的文件。然后再IDE中以文本的方式打开&#xff0c;然后格式化&#xff0c;就可以看到代码。代码中一般是最外层一个svg标签&#xff0c;里面是一个或者多个path。这个时候&#xff0c;我们使用h方法来实…...

已成功见刊检索的国际学术会议论文海报展示(2)

【先投稿先送审】第四届计算机、物联网与控制工程国际学术会议&#xff08;CITCE 2024) 大会官网&#xff1a;www.citce.org 时间地点&#xff1a;2024年11月1-3日&#xff0c;中国-武汉 收录检索&#xff1a;EI Compendex&#xff0c;Scopus 主办单位&#xff1a;四川师范…...

EasyCVR/EasyDSS无人机直播技术助力野生动物监测

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

AI视频教程下载-ChatGPT 生产力 + 时间管理

ChatGPT Productivity Time Management. ChatGPT Productivity ChatGPT 显著提升生产力 不寻常的时间管理技巧。ChatGPT 工作&#xff0c;Chat GPT 自动化&#xff0c;ChatGPT 2023&#xff01; 对关于ChatGPT的讨论感到好奇&#xff0c;想知道如何利用它为自己带来好处吗&a…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...