线程安全(二)synchronized 的底层实现原理、锁升级、对象的内存结构
目录
- 一、基础使用
- 1.1 不加锁的代码实现
- 1.2 加锁的代码实现
- 二、实现原理
- 2.1 synchronized 简介
- 2.2 对象监控器(Monitor)
- 2.3 加锁过程
- 第一步:判断 Owner 指向
- 第二步:进入 EntryList 阻塞
- 第三步:主动进入 WaitSet 等待
- 三、锁升级
- 3.1 对象的内存结构
- 3.2 Mark Word 对象头
- 3.3 Monitor 重量级锁
- 3.4 轻量级锁
- 1)背景:
- 2)加锁过程:
- 3)解锁过程:
- 3.5 偏向锁
- 1)背景:
- 2)加锁过程:
- 3)轻量级锁 vs 偏向锁
- 3.6 总结
一、基础使用
- 假如有这样一个场景:20个用户一起抢10张票。
1.1 不加锁的代码实现
public class TicketDemo {// 票总数private int ticketNum = 10;/*** 抢票*/public void getTicket() {if (ticketNum <= 0) {return;}System.out.println(Thread.currentThread().getName() + " 抢到一张票,剩余:" + ticketNum);// 非原子性操作ticketNum--;}/*** 测试:20个人抢一张票*/public static void main(String[] args) {TicketDemo ticketDemo = new TicketDemo();for (int i = 0; i < 20; i++) {new Thread(ticketDemo::getTicket).start();}}
}
执行结果:
可以看到出现了 超卖问题,一共10张票,当20个线程一起抢票就出现有11个人抢到了票。这是因为如果两个线程同时通过了 if 校验。
所以我们需要对票数的操作进行加锁,保证同一时间只有一个线程来检查和操作票数扣减。
1.2 加锁的代码实现
public class TicketDemo {// 锁private static Object lock = new Object();// 票总数private int ticketNum = 10;/*** 抢票*/public void getTicket() {synchronized (lock) {if 相关文章:
线程安全(二)synchronized 的底层实现原理、锁升级、对象的内存结构
目录 一、基础使用1.1 不加锁的代码实现1.2 加锁的代码实现二、实现原理2.1 synchronized 简介2.2 对象监控器(Monitor)2.3 加锁过程第一步:判断 Owner 指向第二步:进入 EntryList 阻塞第三步:主动进入 WaitSet 等待三、锁升级3.1 对象的内存结构3.2 Mark Word 对象头3.3 …...
【学习笔记】无人机(UAV)在3GPP系统中的增强支持(十四)-无人机操控关键绩效指标(KPI)框架
引言 本文是3GPP TR 22.829 V17.1.0技术报告,专注于无人机(UAV)在3GPP系统中的增强支持。文章提出了多个无人机应用场景,分析了相应的能力要求,并建议了新的服务级别要求和关键性能指标(KPIs)。…...
数电基础 - 半导体存储
目录 一. 简介 一. 只读存储器 二. 可编程只读存储器 三. 可擦除的可编程只读存储器 四. 随机存储器 五. 存储器容量的扩展 六. 总结 一. 简介 半导体存储是数字电路中用于存储数据的重要组成部分。 半导体存储器主要分为两大类:随机存取存储器࿰…...
校园工会体育报名小程序的设计
管理员账户功能包括:系统首页,个人中心,赛事公告管理,球员管理,球队信息管理,比赛信息,比赛报名管理 微信端账号功能包括:系统首页,比赛信息,比赛报名&#…...
2024Datawhale AI夏令营---基于术语词典干预的机器翻译挑战赛--学习笔记
#Datawhale #NLP 1.背景介绍: 机器翻译(Machine Translation,简称MT)是自然语言处理领域的一个重要分支,其目标是将一种语言的文本自动转换为另一种语言的文本。机器翻译的发展可以追溯到20世纪50年代,经历…...
手机下载APP (uniapp/vue)
一、uniapp <template><view class"content"><view class"appName">{{ formData.appName }}</view><view class"appInfo">{{ formData.appInfo }}</view><image class"logo" :src"formDa…...
python数据可视化(5)——绘制饼图
课程学习来源:b站up:【蚂蚁学python】 【课程链接:【【数据可视化】Python数据图表可视化入门到实战】】 【课程资料链接:【链接】】 Python绘制饼图分析北京天气 饼图,是一个划分为几个扇形的圆形统计图表ÿ…...
实习随笔【iviews的Select实现‘与全部互斥’的多选】
在实习中,遇到了如下需求,要求如下: 上面提到了一个需求为,选择全部与选择一个或者多个互斥,我们来看一下如何解决 核心代码 监听value的变化,如果含有‘全部’,且数组长度>1,则删…...
网站架构核心要素
高性能 技术指标:响应时间、吞吐量、并发数 前端优化手段 页面布局:css在前,js在后通信数据量:数据尽量精简缓存:浏览器缓存、cdn异步:ajax 后端优化手段 缓存:反向代理、redis异步&#x…...
XML 解析异常问题解决
问题描述 The parser has encountered more than "64000" entity expansions in this document; this is the limit imposed by the JDK. 在运行 Java 应用程序时,出现了 XML 解析异常。具体表现为: 报错信息显示无法创建 StAX(S…...
C# 匿名方法、Lambda、Linq概念及联系
匿名方法、Lambda表达式与LINQ 匿名方法 概念: 匿名方法是没有名称的方法实现,通常与委托关联使用。它提供了一种在不创建独立命名方法的情况下编写代码块的方式。 语法: delegate void MyDelegate(string message);MyDelegate del dele…...
django ninja get not allowed 能用 put delete
遇到一个奇怪的问题,django-ninja 编写的 get post 方法不能使用 # 获取Material router.get(/material, responseList[MaterialSchemaOut]) paginate(MyPagination) def list_material(request, filters: Filters Query(...)):qs retrieve(request, Material, f…...
服务器操作集合
服务器使用PC作为代理访问外网 1、PC上启动代理,比如nginx 下载nginx:http://nginx.org/en/download.html 修改配置文件,在conf下: http {include mime.types;default_type application/octet-stream;sendfile o…...
论文阅读【时空+大模型】ST-LLM(MDM2024)
论文阅读【时空大模型】ST-LLM(MDM2024) 论文链接:Spatial-Temporal Large Language Model for Traffic Prediction 代码仓库:https://github.com/ChenxiLiu-HNU/ST-LLM 发表于MDM2024(Mobile Data Management…...
【linux基础】linux远程传输三种免交互方式
linux远程传输三种免交互方式 文章目录 linux远程传输三种免交互方式1、使用sshpass工具2、使用expect脚本来输入密码3、SSH 密钥对 1、使用sshpass工具 建立信任关系的做法是最方便和安全的做法,但是在有些场景下(比如远端的authorized_keys是不能随意更改的)&…...
MySQL篇:事务
1.四大特性 首先,事务的四大特性:ACID(原子性,一致性,隔离性,持久性) 在InnoDB引擎中,是怎么来保证这四个特性的呢? 持久性是通过 redo log (重做日志&…...
处理在 electron 中使用开启了懒加载的 el-image 后,窗口最大化或窗口尺寸变化后图片无法显示的问题
文章目录 1、问题描述2、详情动图3、解决思路4、解决方案5、效果展示 1、问题描述 在 electron 中使用 el-image 时,开启了懒加载后,发现只有当窗口滚动后,图片才会显示,即便图片已经处于窗口的可视区域。当拖动窗口使其尺寸变大…...
Electron 进程间通信
文章目录 渲染进程到主进程(单向)渲染进程到主进程(双向)主进程到渲染进程 (单向,可模拟双向) 渲染进程到主进程(单向) send (render 发送)on &a…...
0基础学python-8:if,while,for
目录 前言: 一、选择循环结构 1.if条件语句 2.while 3.for循环 4.break语句 5.continue语句 前言: if、while 和 for 是 Python 中常用的控制流结构,它们分别用于条件判断、循环执行和迭代遍历。这些关键字帮助程序根据条件和数据进行选…...
低空经济持续发热,无人机培训考证就业市场及前景剖析
随着科技的不断进步和社会需求的日益增长,低空经济已成为全球及我国经济增长的新引擎。作为低空经济的重要组成部分,无人机技术因其广泛的应用领域和显著的经济效益,受到了社会各界的广泛关注。为满足市场对无人机人才的需求,无人…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
