线程安全2

文章目录

  • 锁的可重入性
  • 死锁
  • 内存可见性引起的线程安全

锁的可重入性

在这里插入图片描述
直观来看这个代码不能运行
为啥没有出现阻塞?
当前由于是同一个线程,此时的锁对象,就知道了第二次加锁的线程,就是持有锁的线程,第二次操作,就可以直接放行通过,不会出现阻塞

这个特性称为“可重入”

对于可重入锁来说:内部会持有两个信息
1.当前锁是哪个线程持有的
2.加锁次数的计时器
过程描述:
第一次加锁的时候计数器+1(初始情况为0,+1后变成了1,说明当前这个对象被该线程加锁一次)同时记录线程是谁,第二次加锁的时候,发现加锁线程和持有线程是一个线程,第二次应该能够加锁成功,判断当前加锁进程是否持有锁的线程,如果不是同一个线程,阻塞如果是同一个线程,就只是++计数器,即可没有其他操作,此处的计时器(源码是在JVM中,c++代码实现出来的)是关键。

死锁

1.一个线程,一把锁
如果锁是不可重入锁,并且一个线程对这把锁加锁两次就会出现死锁(钥匙锁屋里了·)

2.两个线程,两把锁
线程1获取到锁A
线程2获取到锁B
接下来,1尝试获取B,2尝试获取A,此时会出现死锁

public static void main(String[] args) {Object A = new Object();Object B = new Object();Thread t1 = new Thread(() -> {synchronized (A) {// sleep 一下, 是给 t2 时间, 让 t2 也能拿到 Btry {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}// 尝试获取 B, 并没有释放 Asynchronized (B) {System.out.println("t1 拿到了两把锁!");}}});Thread t2 = new Thread(() -> {synchronized (B) {// sleep 一下, 是给 t1 时间, 让 t1 能拿到 Atry {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}// 尝试获取 A, 并没有释放 Bsynchronized (A) {System.out.println("t2 拿到了两把锁!");}}});t1.start();t2.start();}
}

3.N个线程M把锁
在这里插入图片描述
在这里插入图片描述
线程一执行到22行
在这里插入图片描述
线程二执行到37行
在这里插入图片描述

在这里插入图片描述
这些线程安全的类也不是绝对的线程安全,只是自带了锁

内存可见性引起的线程安全

public class Test3 {private  static int flag = 0;public static void main(String[] args) {Thread t1 = new Thread(()->{while(flag == 0){}System.out.println("循环结束");});Thread t2 = new Thread(()->{System.out.println("请输入flag的值:");Scanner scanner = new Scanner(System.in);flag = scanner.nextInt();});t1.start();t2.start();}
}

在这个代码中,预期通过t2线程输入的整数,只要输入的不是0,就可以是t1线程结束。
t2要等待用户输入,无论t1先启动还是t2先启动,在等待用户输入的过程中,t1必然循环了很多次了
但是当我们输入非0值,没有输出结果,
原因:内存可见性引起的线程安全,while(flag == 0)由两个指令组成,
1.load读取内存的flag的值到cpu寄存器中
2.拿着寄存器的值与0进行比较
t1线程反复进行1,2操作,由于频繁执行load和条件跳转,load的开销大,并且load的结果又没有变化,此时JVM产生了怀疑,于是JVM就对代码进行了优化,load就被优化掉了,相当于不再重复读内存,直接使用寄存器中之前缓存的值,以提高循环的执行速度,t2修改了内存,但是t1没有看到,就导致了内存可见性问题
为了解决代码优化问题,Java提供了volatile就可以使上述的优化被强制关闭

private volatile static int flag = 0;

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

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

相关文章

前端开发必备:掌握正则表达式,轻松应对复杂的表单验证

前言 在前端开发中,经常需要处理 URL 地址、校验手机号合法性、提取域名等。正则表达式是一种常用的工具。通过使用正则表达式,我们可以对用户输入进行有效的验证,确保数据的合法性和完整性。本文将介绍一些常见的正则表达式,帮助…

C++面试:单例模式、工厂模式等简单的设计模式 创建型、结构型、行为型设计模式的应用技巧

理解和能够实现基本的设计模式是非常重要的。这里,我们将探讨两种常见的设计模式:单例模式和工厂模式,并提供一些面试准备的建议。 目录 单例模式 (Singleton Pattern) 工厂模式 (Factory Pattern) 面试准备 1. 理解设计模式的基本概念…

SpringMVC中拦截器的简单使用

步骤一:创建拦截器类 首先,我们需要创建一个拦截器类,该类需要实现HandlerInterceptor接口。这个接口定义了三个方法,分别在请求处理前、请求处理后和视图渲染后执行。 import org.springframework.web.servlet.HandlerIntercep…

使用JDK自带的jvisualvm工具查看堆dump文件【回顾】

JDK自带的jvisualvm的使用 打开方式: 直接命令行输入:jvisualvm ,然后回车​​​​​​​ ​​ 或者去jdk的bin目录下找到打开 安装visual GC插件 检测死锁 再点击“死锁 dump”就可以看到死锁的线程信息了;

LeeCode前端算法基础100题(17)- 罗马数字转整数

一、问题详情: 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2 写做 II ,即为两个并列的 1 …

linux c语言记录内核错误

在 Linux C 程序中,将信息记录在日志文件中通常使用 syslog 守护进程来实现。你可以使用 syslog() 函数将自定义的错误信息记录到系统日志中。另外,你也可以使用开源库如 liblog,log4c 等来更加灵活地记录日志。 下面是一个简单的示例代码&a…

Vulnhub靶机:driftingblues 4

一、介绍 运行环境:Virtualbox 攻击机:kali(10.0.2.15) 靶机:driftingblues4(10.0.2.20) 目标:获取靶机root权限和flag 靶机下载地址:https://www.vulnhub.com/entr…

【Python数据分析系列】实现txt文件与列表(list)相互读写转换(源码+案例)

这是Python数据分析系列原创文章,我的第199篇原创文章。 一、问题 平时在做数据分析或者程序开发的时候,需要将中间的一些结果或最后的处理结果保存下来,比如保存为txt格式的文本文件,这就涉及列表与txt之间的一种读取和写入操作…

spring cloud feign demo

1. 工程结构 2. 父工程pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.…

JVM实战(17)——模拟对象晋升

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 学习必须往深处挖&…

django中orm模型类多种用法

模型准确且唯一的描述了数据。它包含您储存的数据的重要字段和行为。一般来说&#xff0c;每一个模型都映射一张数据库表。 每个模型都是一个 Python 的类&#xff0c;这些类继承 django.db.models.Model模型类的每个属性都相当于一个数据库的字段。利用这些&#xff0c;Djang…

(每日持续更新)jdk api之FileInputStream基础、应用、实战

博主18年的互联网软件开发经验&#xff0c;从一名程序员小白逐步成为了一名架构师&#xff0c;我想通过平台将经验分享给大家&#xff0c;因此博主每天会在各个大牛网站点赞量超高的博客等寻找该技术栈的资料结合自己的经验&#xff0c;晚上进行用心精简、整理、总结、定稿&…

将PDF发票转换为excel、xml结构化数据的完美解决方案

随着电子发票的普及&#xff0c;越来越多的企业和个人开始使用PDF格式的电子发票。然而&#xff0c;有时我们需要将电子发票转换为XML格式以便于处理和分析。本文将介绍如何将收到的PDF发票下载为excel、xml文件。首先&#xff0c;我们需要明确一点&#xff0c;PDF是一种基于图…

1. FPGA概述

文章目录 1. 什么是FPGA2. 学习FPGA有什么用3. 学习FPGA需要何种先决条件 1. 什么是FPGA 这个问题太low了&#xff0c;身处数字时代&#xff0c;从事电子信息行业&#xff0c;居然不知道FPGA&#xff1f;岂非笑谈&#xff1f; 介绍FPGA的资料太多了&#xff0c;还是从它的字面…

Could NOT find Threads (missing: Threads_FOUND)

具体错误 -- Performing Test CMAKE_HAVE_LIBC_PTHREAD -- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed -- Looking for pthread_create in pthreads -- Looking for pthread_create in pthreads - not found -- Looking for pthread_create in pthread -- Looking for…

C#编程-属性和反射

属性和反射 属性是将元数据信息和行为添加到应用程序代码中的简单技术。属性是允许您将声明信息添加到程序的元素。此声明信息在运行时用途广泛,可使用应用程序开发工具在设计时使用。 介绍属性 对象是由其属性值描述的。例如,汽车可以使用它的构造、型号或颜色来描述。类似…

ART-Adversarial Robustness Toolbox检测AI模型及对抗攻击的工具

一、工具简介 Adversarial Robustness Toolbox 是 IBM 研究团队开源的用于检测模型及对抗攻击的工具箱&#xff0c;为开发人员加强 AI模型被误导的防御性&#xff0c;让 AI 系统变得更加安全&#xff0c;ART支持所有流行的机器学习框架 &#xff08;TensorFlow&#xff0c;Ker…

SpringMVC RESTful案例

文章目录 1、准备工作2、功能清单3、具体功能&#xff1a;访问首页a>配置view-controllerb>创建页面 4、具体功能&#xff1a;查询所有员工数据a>控制器方法b>创建employee_list.html 5、具体功能&#xff1a;删除a>创建处理delete请求方式的表单b>删除超链接…

Web3社交治理:用户参与决策的新模式

Web3时代的到来不仅仅带来了区块链技术的创新&#xff0c;还为社交治理带来了全新的模式。传统社交平台上的决策权通常集中在平台的运营方&#xff0c;而Web3社交治理的兴起意味着用户能够更直接地参与到社交平台的决策过程中。本文将深入探讨Web3社交治理的背景、工作原理以及…

帆软笔记-决策表报对象使用(两表格联动)

效果描述如下&#xff1a; 数据库中有个聚合商表&#xff0c;和一个储能表&#xff0c;储能属于聚合商&#xff0c;桩表中有个字段是所属聚合商。 要求帆软有2个表格&#xff0c;点击某个聚合商&#xff0c;展示指定的储能数据。 操作&#xff1a; 帆软选中表格单元&#xf…