多线程05

前言

前面我们说到了死锁以及线程可见性的问题

我们将线程可见性主要归结于是JVM自身的一个bug

一个线程写一个线程读

会将一直不变的变量优化到直接从寄存器中读取,而不是缓存等读取,因为这样我们就设置了使用volatile关键字使得用到这个变量的时候必须从内存中读取数据

死锁主要是四个原因导致:不可抢占,互斥使用,循环等待,请求保持

其中只有循环等待是最好破坏的,我们可以使用规定线程的加锁顺序来破坏这种循环等待的效果

本节我们将讨论wait和notify两个方法的使用 

为什么引入这两个方法,有什么用?

和join方法类似,这两个方法还是用来在应用层面上规定代码的执行顺序,事实上在操作系统内核中线程的调度仍然是无序的

这里的干预其实就是让某个线程主动放弃了去cpu执行的权利,相当于放弃了被调度的机会

举个例子:

此时a线程想去atm中取钱,b线程和c线程想进去存钱,恰好此时a拿到了锁,进去了atm房间

此时a就可以一直占用atm机器等待,加入发现没钱出来,a仍然在行列中竞争锁,所以a一直能持有锁(概率问题,就像我跟你分手了,我们复合的概率更大一样),此情况就称之为线程饿死,因为其他的线程都拿不到锁,执行不了自己的代码

(就是某个线程一直反复获取锁,但是又不执行实质性的逻辑)

wait做了什么??

wait方法实际上是做了三件事情

1.释放锁

2.阻塞等待

3.当其他线程调用notify方法的时候,解除阻塞状态,持有锁之后继续运行代码

join和notify的区别

join方法是指假如在主线程中调用t1.join

此时主线程就会等t1线程执行完才会继续执行

而wait方法除非有线程去唤醒他,他会一直等到枯树开出花

当然,我们也是可以设置wait的最大时间的,也就是等不到结果就直接不等了

产生阻塞的几种原因

join/wait  BLOCKED

sleep       TIMED_WAITING

synchronized BLOCKED

由于wait是object类中的一个方法,所以随便拿个对象都可以使用wait方法,但是得持有锁才行,不然会发生异常

我们一般在synchronized代码块中使用

注:调用wait的对象一般和synchronized的锁一致

一个简单的使用案例

public static void main(String[] args) {//统一对象进行加锁解锁Object lock = new Object();Thread t1 = new Thread(()->{synchronized (lock){System.out.println("t1 wait 之前");try {lock.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("t1 wait 之后");}});Thread t2 = new Thread(()->{synchronized (lock){try {Thread.sleep(5000);System.out.println("notify之前");lock.notify();System.out.println("notify之后");} catch (InterruptedException e) {throw new RuntimeException(e);}}});t1.start();t2.start();}

此时的结果就是,t1线程在执行过打印效果后,会进入阻塞状态,然后t2睡眠5000ms之后会执行一次打印动作,然后让t1解除阻塞状态,最后执行完下一次打印后释放锁

注:notify方法只会唤醒阻塞的线程,并不会释放锁

注:wait和notify方法是成套使用的,两者依靠对象联系起来

假如这里我们使用object1对象来wait这个线程

再使用objcet2是唤不醒这个线程的

多线程知识点小结

1.线程的特性,线程和进程的区别

2.Thread类创建线程的几种方式

3.Thread类的一些属性

4.启动线程

5.终止线程

6.等待线程

7.线程休眠

8.获取线程引用

9.线程状态

10.线程安全问题

        10.1 线程安全产生的原因及解决方法

        10.2 死锁问题

        10.3 内存可见性问题

11.线程的wait和notify...

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

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

相关文章

vscode集成git

1、首先电脑要安装git 打开git官网地址:Git进行下载,如下图界面: 如图片中描述:一般进入官网后会识别电脑对应系统(识别出了我的电脑是Windows系统 。如果未识别到电脑系统,可在左侧选择自己电脑对应的系统…

【yolov5人行道-斑马线目标检测】

yolov5人行道-斑马线目标检测 数据集yolov5人行道-斑马线目标检测检测模型 数据集 YOLOv5是一种目标检测算法,可以用于检测图像中的人行道-斑马线。在目标检测领域,YOLOv5通过结合多种技术手段,包括使用Mosaic数据增强操作、自适应锚框计算与…

方差分析(F检验)用于特征选择的Python实现

方差分析(F检验)又称ANOVA,方差齐性检验,是一种用来捕捉每个特征变量与响应变量之间线性关系的过滤方法,实现路径是针对两个及两个以上分组的样本均值进行差异显著性检验,基本思想是将不同分组的样本均值之…

基于 Gin 的 HTTP 代理 Demo(2)

一周后勘误: 我这里实现的严格来说还是 HTTP 代理,只不过是通过隧道的方式传输非 HTTP 的流量,这里是 HTTPS 流量。尽管它可以传输 HTTPS 流量,它也不算是 HTTPS 代理。 上次写了 基于 Gin 的 HTTP 代理 Demo 之后,对…

ESP32-Web-Server 实战编程-使用文件系统建立强大的 web 系统

ESP32-Web-Server 实战编程-使用文件系统建立强大的 web 系统 概述 在前述章节我们讲述了在网页端控制多个 GPIO 的案例。当程序开始变得复杂,让一些功能“自动起来”是一个好的选择。 在前面的示例中,我们需要在后端为每个前端代码的 URL 指定一个对…

Maven——使用Nexus创建私服

私服不是Maven的核心概念,它仅仅是一种衍生出来的特殊的Maven仓库。通过建立自己的私服,就可以降低中央仓库负荷、节省外网带宽、加速Maven构建、自己部署构件等,从而高效地使用Maven。 有三种专门的Maven仓库管理软件可以用来帮助大家建立…

Redis基础系列-安装Redis

Redis基础系列-安装Redis 文章目录 Redis基础系列-安装Redis1. 环境要求2. 下载redis3. 安装4. 配置5 参考与感谢 1. 环境要求 (安装C语言编译环境)redis是用C语言开发的,所以需要安装C语言编译环境,中途可能会出现询问你是否需要可以安装&a…

VS Code C++可视化调试配置Natvis,查看Qt、STL变量内容

VS Code C可视化调试配置Natvis 使用GlobalVisualizersDirectory Windows下 C:\Users\YourName\.vscode\extensions\ms-vscode.cpptools-1.18.5-win32-x64\debugAdapters\vsdbg\bin\Visualizers\Linux下 ~\.vscode\extensions\ms-vscode.cpptools-1.18.5-win32-x64\debugAd…

SS6850H16V/1A 两通道 H 桥驱动芯片(适合 12V 系统产品的电机驱动)

SS6850H 是一款 2 通道 H 桥驱动芯片。 最适合 12V 系统产品的电机驱动。芯片每个 H 桥可提供最大峰值电流 1A 和均方根电流 0.7A(在 12V 和 Ta 25C 适当散热条件下),可以驱动两台直流电 机,一台并联直流电机,也可以驱动步进电机&#xff0c…

替代升级虚拟化 | ZStack Cloud云平台助力中节能镇江公司核心业务上云

数字经济正加速推动各行各业的高质量升级发展,云计算是数字经济的核心底层基础设施。作为云基础软件企业,云轴科技ZStack 坚持自主创新,自研架构,产品矩阵可全面覆盖数据中心云基础设施,针对虚拟化资源实现纳管、替代和…

IDEA断点实用小技巧

IDEA断点实用小技巧 1. 多线程调试2. 断点修改变量值3. 断点条件设置4. 回退断点5. 中断Debug6. 计算表达式 1. 多线程调试 背景:默认情况下,IDEA断点时会阻塞所有请求,此时外部想再发送一个请求也会被阻塞,如图所示,…

Yolov8实现瓶盖正反面检测

一、模型介绍 模型基于 yolov8n数据集采用SKU-110k,这数据集太大了十几个 G,所以只训练了 10 轮左右就拿来微调了 基于原木数据微调:训练 200 轮的效果 10 轮SKU-110k 20 轮原木 200 轮瓶盖正反面 微调模型下载地址https://wwxd.lanzouu.co…