线程安全3--wait和notify

文章目录

  • wait and notify(等待通知机制
  • notify
  • 补充

wait and notify(等待通知机制

引入wait notify就是为了能够从应用层面上,干预到多个不同线程代码的执行顺序,这里说的干预,不是影响系统的线程调度策略(内核里调度线程,仍然是无序调度)
相当于是在应用程序代码中,让后执行的线程,主动放弃被调度的机会,就可以让先执行的线程,先把对应代码执行完了
举例:
在ATM机上取钱
在这里插入图片描述
ATM通过锁来互斥
第一个人,先进去,发现ATM没钱,然后出来了,但是和其他人来竞争这个ATM,参与到了锁竞争中,此时完全有可能第一个人再次拿到这个锁,如果反复如此,就会导致第一个人反复获取到锁,但又无法完成实质性的逻辑,导致“线程饿死”。
这种情况就是严重的bug,当第一个人发现自己要执行的逻辑,前提条件不具备,在这种情况下,应该主动放弃对锁的竞争,一直到条件具备,此时再解除阻塞,参与锁竞争,这个时候就要用到wait和notify
在这里插入图片描述
join是等待另一个线程执行完,才继续执行
wait则是等待另一个线程通过notify进行通知(不要求另一个线程必须执行完)
wait进入阻塞,只能说明自己释放锁了
其他线程是否拿到了锁,另当别论

阻塞产生的原因有好几种:
1.sleep TIMED_WAITING
2.join/wait WAITING
3.synchronized BLOCKED

Object object = new Object();object.wait();

随便拿一个对象都能调用wait但是运行起来会报异常
在这里插入图片描述
不合法监视状态异常
原因:wait一旦调用就会释放锁,释放锁的前提是拿到锁,所以,wait必须放到synchronized里面使用。
wait锁对象必须和synchronized锁对象一致

public class Test4 {public static void main(String[] args) {Object object = new Object();Thread t1 = new Thread(()->{synchronized (object){System.out.println("wait前");try {object.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("wait后");}});t1.start();}
}

输出结果:

wait前

代码一直没有结束

在Java监视和管理控制台上:
在这里插入图片描述

notify

锁被wait就需要来唤醒锁,notify就是来唤醒锁的
notify可以不放在synchronized里面,但是Java规定notify必须放在synchronized里面

public class Test4 {public static void main(String[] args) throws InterruptedException {Object object = new Object();Thread t1 = new Thread(()->{synchronized (object){System.out.println("wait前");try {object.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("wait后");}});Thread t2 = new Thread(()->{try {Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized(object){System.out.println("notify前");object.notify();System.out.println("notify后");}});t1.start();t2.start();}
}

运行结果:

wait前
notify前
notify后
wait后

线程2使用sleep的原因
因为线程调度是随机的,不确定线程1还是线程2先运行,如果线程2先运行就达不到我们预期的结果,所以sleep线程2,让线程1先运行,先执行wait,再执行notify。

上述代码运行执行过程:
1.t1先执行起来后,就会立即拿到锁,并打印wait前,然后进入wait方法(释放锁+阻塞等待)
2.t2执行起来,先进行sleep五秒(为了让t1先拿到锁)
3.t2sleep结束后,由于t1是wait状态,锁是释放的,t2就能拿到锁,接下来打印notify前,执行notify操作,唤醒t1
4.由于t2还没有释放锁,t1想要获取锁,可能会出现阻塞,和t2锁竞争导致
5.t2打印notify后,释放锁,t2执行完毕,t1获取到锁,打印wait后

补充

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

uni-app应用设置 可以根据手机屏幕旋转进行 (横/竖) 屏切换

首先 我们打开项目的 manifest.json 在左侧导航栏中找到 源码视图 然后找到 app-plus 配置 在下面加上 "orientation": [//竖屏正方向"portrait-primary",//竖屏反方向"portrait-secondary",//横屏正方向"landscape-primary",//横屏…

IDEA启动应用时报错:错误: 找不到或无法加载主类 @C:\Users\xxx\AppData\Local\Temp\idea_arg_filexxx

IDEA启动应用时报错,详细错误消息如下: C:\devel\jdk1.8.0_201\bin\java.exe -agentlib:jdwptransportdt_socket,address127.0.0.1:65267,suspendy,servern -XX:TieredStopAtLevel1 -noverify -Dspring.output.ansi.enabledalways -Dcom.sun.management…

基于以太坊的智能合约开发Solidity(事件日志篇)

//声明版本号(程序中的版本号要和编译器版本号一致) pragma solidity ^0.5.17; //合约 contract EventTest {//状态变量uint public Variable;//构造函数constructor() public{Variable 100;}event ValueChanged(uint newValue); //事件声明event Log(…

class064 Dijkstra算法、分层图最短路【算法】

class064 Dijkstra算法、分层图最短路【算法】 算法讲解064【必备】Dijkstra算法、分层图最短路 code1 743. 网络延迟时间 // Dijkstra算法模版(Leetcode) // 网络延迟时间 // 有 n 个网络节点,标记为 1 到 n // 给你一个列表 times&…

法律服务网站建设效果如何

律师事务所及法律知识咨询机构等往往是众多人群需求的服务,服务多样化及内容多元化,市场中也有大量品牌,在实际消费服务中大多以本地事务所为主,而线上咨询服务则一般没有区域限制,同行增多及人们知识获取渠道增加&…

C++-引用和指针区别

文章目录 1.变量的组成2.指针2.1 定义2.2 使用指针操作变量2.3 为什么使用指针 3.引用3.1 定义3.2 引用注意事项 4.引用和指针的区别 1.变量的组成 变量的组成:变量地址,变量名,变量值 例: int i 12;2.指针 2.1 定义 指针用于存…

如何为游戏角色3D模型设置纹理贴图

在线工具推荐: 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 当谈到游戏角色的3D模型风格时,有几种不同的风格&#xf…

Mybatis中的查询操作

单表查询 单表查询在《初始Mybatis》中已经介绍过&#xff0c;这里就不在介绍了。咱们这里只说单表查询中的“like查询”。like查询单独使用#{}报错 <select id"selectByKeyword" resultType"com.example.demo.entity.Userinfo">select * from use…

计网Lesson8 - NAT技术与链路层概述

文章目录 NAT 技术1. 因特网的接入方式2. 公网和私网3. NAT 技术 链路层1. 数据链路层概述2. 数据链路层的三个问题2.1 封装成帧2.2 透明传输2.3 差错检测 NAT 技术 1. 因特网的接入方式 光猫将电信号转换为数字信号发送给路由器 光纤入户 光纤传递的就是数字信号&#xff0c…

python+pytest接口自动化(12)-自动化用例编写思路 (使用pytest编写一个测试脚本)

经过之前的学习铺垫&#xff0c;我们尝试着利用pytest框架编写一条接口自动化测试用例&#xff0c;来厘清接口自动化用例编写的思路。 我们在百度搜索天气查询&#xff0c;会出现如下图所示结果&#xff1a; 接下来&#xff0c;我们以该天气查询接口为例&#xff0c;编写接口测…

每日一练2023.12.9—— 矩阵A乘以B【PTA】

题目链接&#xff1a;L1-048 矩阵A乘以B 题目要求&#xff1a; 给定两个矩阵A和B&#xff0c;要求你计算它们的乘积矩阵AB。需要注意的是&#xff0c;只有规模匹配的矩阵才可以相乘。即若A有Ra​行、Ca​列&#xff0c;B有Rb​行、Cb​列&#xff0c;则只有Ca​与Rb​相等时&a…

Linux Shell 基础命令

Linux 是一个开源的操作系统&#xff0c;其命令行界面是它的重要组成部分。在这个界面下&#xff0c;Shell 是一个能够与操作系统进行交互的工具。Shell 是一种程序&#xff0c;它能够接收用户输入的命令&#xff0c;并将这些命令发送到操作系统中进行处理。 在 Linux 中&…

VINS-MONO代码解读5----vins_estimator(marginalization部分)

文章目录 0. 前言1.1 Marginalization Pipiline 1. marg factor构建1.1 变量及维度理解1.2 IMUFactor1.3 ProjectionTdFactor(ProjectionFactor)1.4 MarginalizationFactor( e p e_p ep​推导更新&#xff0c;FEJ解决的问题)1.4.1 先验残差的更新1.4.2 先验Jacobian的更新 2. R…

windows install git

refer: https://developers.weixin.qq.com/miniprogram/dev/devtools/wechatvcs.html https://blog.csdn.net/weixin_40228200/article/details/128451324 在使用小程序的时候&#xff0c;需要初始化项目&#xff0c;需要注册Git账号 1.在本地确认cmd没有安装Git,进入Git官网…

docker:安装mysql以及最佳实践

文章目录 1、拉取镜像2、运行容器3、进入容器方式一方式二方式三容器进入后连接mysql和在宿主机连接mysql的区别 持久化数据持久化数据最佳实践 1、拉取镜像 docker pull mysql2、运行容器 docker run -d -p 3307:3306 --name mysql-container -e MYSQL_ROOT_PASSWORD123456 …

Botton进一步了解(点击事件)

点击事件和长按事件 监听器&#xff1a;专门监听控件的动作行为。只有控件发生了指定的动作&#xff0c;监听器才会触发开关区执行对应的代码逻辑。按钮控件有两种常用的监听器&#xff1a; 点击监听器&#xff1a;通过setOnClickListener方法设置。按钮被按住少于500ms时会触…

2023济南大学acm新生赛题解

通过答题情况的难度系数&#xff1a; 签到&#xff1a;ACI 铜牌题&#xff1a;BG 银牌题&#xff1a;EF 金牌题&#xff1a;DHJKO 赛中暂未有人通过&#xff1a;LMNP A - AB Problem 直接根据公式计算就行。 #include<stdio.h> int main(){int a,b;scanf("%…

安卓MediaRecorder(2)录制源码分析

文章目录 前言JAVA new MediaRecorder() 源码分析android_media_MediaRecorder.cpp native_init()MediaRecorder.java postEventFromNativeandroid_media_MediaRecorder.cpp native_setup() MediaRecorder 参数设置MediaRecorder.prepare 分析MediaRecorder.start 分析MediaRec…

【Angular开发】Angular在2023年之前不是很好

做一个简单介绍&#xff0c;年近48 &#xff0c;有20多年IT工作经历&#xff0c;目前在一家500强做企业架构&#xff0e;因为工作需要&#xff0c;另外也因为兴趣涉猎比较广&#xff0c;为了自己学习建立了三个博客&#xff0c;分别是【全球IT瞭望】&#xff0c;【架构师酒馆】…

SSL证书更新

首先&#xff0c;我们需要理解为什么需要更新SSL证书。SSL证书的有效期通常为一年。一旦证书过期&#xff0c;浏览器会显示警告&#xff0c;提示用户该网站的SSL证书已经过期&#xff0c;这可能会导致用户对网站的信任度下降&#xff0c;甚至直接离开网站。此外&#xff0c;一些…