Java 基础(3)—synchornized 关键字简单理解
一、synchronized 修饰同步代码块
用 synchronized 修饰代码段作为同步锁,代码如下:
public class LockDemo {public Object object = new Object();public void show(){synchronized (object) {System.out.println(">>>>>>hello world!");}}public static void main(String[] args) {new LockDemo().show();}
}
直接运行 main() 方法让 LockDemo 类编译下,然后定位到具体 LockDemo.class 类文件路径处,通过 javap 指令查看底层代码,如下:
javap -c LockDemo.class

从上图中发现底层是由 monitorenter、monitorexit 去实现同步操作的。
但是这里会发现一个 monitorenter 对应着两个 monitorexit,按理加锁和解锁不应该是两个操作么? 怎么来了两个解锁?其实这样设计是为了保证出现异常时能够把锁释放,不会让程序卡死。但是并不是一定是1:2,比如如下代码:
public class LockDemo {public Object object = new Object();public void show(){synchronized (object) {System.out.println(">>>>>>hello world!");throw new RuntimeException(">>>>>>异常");}}public static void main(String[] args) {new LockDemo().show();}
}
通过 javap 命令查看如下图示:

通过 athrow 一直把异常抛到最外层,然后最后 monitorexit 释放锁。总结一句话就是:synchornized 锁是一对出现的,但是为了能够在异常环境下锁能够释放,加了善尾处理。
二、synchornized 修改方法
代码如下:
public class LockDemo {public Object object = new Object();public void show(){synchronized (object) {synchronized (this) {System.out.println(">>>>>>hello world!");}}}public static synchronized void sop() {}public static void main(String[] args) {new LockDemo().show();}
}
通过 javap -v LockDemo.class 命令查看字节码,如下图示:
提示:通过 java -v Xxx 查看到更全面的信息

方法级别的同步是隐形的,无须通过字节码指令控制,它实现在方法调用和返回操作之中。虚拟机可以从方法常量池中方法表结构中的 ACC_SYNCHRONIZED 方法标识得知这个方法是否声明为同步方法,调用时,调用指令会检查方法的 ACC_SYNCHRONIZED 访问标识符是否被设置,如果设置,执行线程就需要先成功持有 Montior 管程,然后才能够执行该方法,其他线程都无法获取到同一个管程。如果同步方法在运行期间抛出异常,且在方法内无法处理,那这个同步方法所持有的管程将在异常抛出到同步方法边界之外自动释放。
三、什么是 Monitor 监视器?
在 HotSpot 虚拟机中,Monitor 是一种用于实现同步的机制。Monitor 可以确保在多线程环境下,同一时间只有一个线程可以访问临界区(即共享资源),从而保证线程安全。
在 Java 中,每个对象都有一个 Monitor,可以通过 synchronized 关键字来获得该对象的 Monitor。当线程进入 synchronized 块时,它会尝试获取对象的 Monitor,如果该 Monitor 正在被其他线程持有,则当前线程将被阻塞,直到 Monitor 可用。当线程退出 synchronized 块时,它将释放对象的 Monitor,这样其他线程就可以获取 Monitor 并进入 synchronized 块。
以下是一个简单的示例,演示了如何使用 synchronized 关键字获取对象的 Monitor,以保证线程安全:
class Counter {private int count = 0;public synchronized void increment() {count++;}public synchronized void decrement() {count--;}public synchronized int getCount() {return count;}
}class Main {public static void main(String[] args) {Counter counter = new Counter();// 创建 1000 个线程,每个线程分别执行 1000 次增加和减少操作for (int i = 0; i < 1000; i++) {new Thread(() -> {for (int j = 0; j < 1000; j++) {counter.increment();counter.decrement();}}).start();}// 等待所有线程执行完毕try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}// 输出最终计数器的值System.out.println(counter.getCount()); // 0}
}
在上面的代码中,我们创建了一个名为 Counter 的类,它包含一个计数器变量 count 和三个同步方法 increment()、decrement() 和 getCount()。在这些方法中,我们使用 synchronized 关键字获取对象的 Monitor,以确保在多线程环境下对计数器的操作是线程安全的。
在主方法中,我们创建了 1000 个线程,每个线程分别执行 1000 次增加和减少操作,从而对计数器进行了大量的并发修改。最后,我们输出计数器的值,期望得到 0,以确保所有操作都是正确的。
Monitor 底层采用 ObjectMonitor.cpp jvm 实现,并且每个对象都是天生带着一个 Monitor 监视器。
看到初始化 ObjectMonitor 构造方法,源码如下图示:

| 属性 | 属性描述 |
|---|---|
| _owner | 指向持有 ObjectMonitor 对象的线程 |
| -WaitSet | 存放处于 wait 状态的线程队列 |
| _EntryList | 存放处于等待锁 block 状态的线程队列 |
| _recursions | 锁重入次数 |
| _count | 用来记录该线程获取锁的次数 |
相关文章:
Java 基础(3)—synchornized 关键字简单理解
一、synchronized 修饰同步代码块 用 synchronized 修饰代码段作为同步锁,代码如下: public class LockDemo {public Object object new Object();public void show(){synchronized (object) {System.out.println(">>>>>>hell…...
【Linux】调试工具gdb的使用
环境:centos7.6,腾讯云服务器Linux文章都放在了专栏:【Linux】欢迎支持订阅🌹前言在前文,我们已经讲解了vim工具以及gcc/g的使用,我们可以进行编写代码以及编译代码了,但是还没有学习如何在Linu…...
大数据知识图谱项目——基于知识图谱的医疗知识问答系统(详细讲解及源码)
基于知识图谱的医疗知识问答系统 一、项目概述 本项目基于医疗方面知识的问答,通过搭建一个医疗领域知识图谱,并以该知识图谱完成自动问答与分析服务。本项目以neo4j作为存储,基于传统规则的方式完成了知识问答,并最终以关键词执…...
威马汽车:跃马扬鞭未竟,鞍马劳顿难行?
“活下去,像牲口一样地活下去。” 威马汽车创始人、董事长兼CEO沈晖1月在社交媒体上分享的电影台词,已然成为威马近况的真实写照。 来源:新浪微博威马汽车沈晖Freeman 最近,网上出现了大量关于“威马汽车将实施全员停薪留职”的…...
【网络】网络基础
🥁作者: 华丞臧. 📕专栏:【网络】 各位读者老爷如果觉得博主写的不错,请诸位多多支持(点赞收藏关注)。如果有错误的地方,欢迎在评论区指出。 推荐一款刷题网站 👉 LeetCode刷题网站 文章…...
Linux系统之Uboot、Kernel、Busybox思考之三
目录 三 内核的运行 5-中断子系统 6 锁、延迟与原子上下文 7 内存管理子系统 8 驱动的两类框架 三 内核的运行 5-中断子系统 中断子系统的数据结构及设计思想。 中断子系统需要解决中断管理的问题。 如果系统中断较少的话,其管理就不用设计这样一个中断子系统这…...
FPGA 20个例程篇:20.USB2.0/RS232/LAN控制并行DAC输出任意频率正弦波、梯形波、三角波、方波(一)
在最后一个例程中笔者精挑细选了一个较为综合性的项目实战,其中覆盖了很多知识点,也是从一个转产产品中所提炼出来的,所以非常贴近实战项目。 整个工程实现了用户通过对上位机PC端人机界面的操作,即可达到控制豌豆开发并行DAC输出…...
性能测试学习和性能瓶颈分析路线
很多企业招聘都只写性能测试,会使用LR,jmeter工具。其实会使用jmeter和LR进行性能测试还只是性能测试的第一步,离真正的性能测试工程师还很远,笔者也还在路上 .。 性能测试,都是要求测试系统性能,系统自然…...
达梦数据库(DM8)集成使用 Geoserver(2.22.2) 以及其他对应版本详解
达梦数据库(DM8)集成使用 Geoserver(2.22.2) 以及其他对应版本详解系统环境版本Geoserver 驱动对应版本达梦 8 集成 Geoserver 过程试错过程问题总结项目需要国产化,选择使用达梦数据库,在技术测试阶段&…...
全开源无加密的RuleApp文章社区APP客户端源码
内容目录一、详细介绍二、效果展示1.部分代码2.效果图展示三、学习资料下载一、详细介绍 开源无加密的文章社区客户端源码分享 RuleApp文章社区,VIP会员,写作投稿积分商城,付费模块集成,多平台兼容这是一款开源免费,界…...
基于springboot校园二手市场平台
一、项目简介 本项目是一套基于springboot校园二手市场平台,主要针对计算机相关专业的正在做bishe的学生和需要项目实战练习的Java学习者。 包含:项目源码、数据库脚本等,该项目可以直接作为bishe使用。 项目都经过严格调试,确保…...
维度建模基本流程总结
一、维度建模基本流程图数据RD进行业务调研和数据现状调研,产出符合相关模版规范的业务知识文档和数据现状文档。数据PM也会调研相关业务产出需求设计文档,三方参与需求评审,评审通过后基建数据RD进行需求拆解,产出技术方案&#…...
RocketMQ事务消息
RocketMQ事务消息 RocketMq提供的一种高级消息类型,支持在分布式场景下面保障消息生产和本地事务的一致性 生产者将消息发送到服务端服务端将消息持久化成功后,向生产者返回ACK确认消息发送成功,此时消息状态为待投递,这种状态下的消息称之为…...
大数据处理 - 双层桶划分
分桶法简介其实本质上还是分而治之的思想,重在“分”的技巧上!适用范围: 第k大,中位数,不重复或重复的数字基本原理及要点: 因为元素范围很大,不能利用直接寻址表,所以通过多次划分,逐步确定范围…...
NFC标签读写器隐私协议
【标签读写器】(以下简称“我们”)深知个人信息对您的重要性,并会尽全力保护您的个人信息安全可靠。我们致力于维持您对我们的信任,恪守以下原则,保护您的个人信息:权责一致原则、目的明确原则、选择同意原…...
DocEE:一种用于文档级事件抽取的大规模细粒度基准 论文解读
DocEE: A Large-Scale and Fine-grained Benchmark for Document-level Event Extraction 论文:NAACL2022.pdf (tongmeihan1995.github.io) 代码:tongmeihan1995/DocEE: DocEE: A Large-Scale and Fine-grained Benchmark for Document-level Event Ext…...
ImageCombiner设计源码详解
前言在前面的博客中介绍了一款Java的海报生成器ImageCombiner,原文地址:拿来就用的Java海报生成器ImageCombiner(一),在博文中简单介绍了一下代码以及一个真实的生成案例。但是对源码的介绍不多,本文就针对源码进行深入…...
python基础 | python基础语法
文章目录📚基础语法🐇输入和输出🥕print()输出🥕input()输入🐇 变量的命名🐇条件判断🥕单向判断🥕双向判断🥕多向判断🥕if嵌套🥕三元表达式&#…...
YOLOv6-3.0-目标检测论文解读
文章目录摘要算法2.1网络设计2.2Anchor辅助训练2.3自蒸馏实验消融实验结论论文: 《YOLOv6 v3.0: A Full-Scale Reloading 》github: https://github.com/meituan/YOLOv6上版本参考 YOLOv6摘要 YOLOv6 v3.0中YOLOv6-N达到37.5AP,1187FPS&…...
JAVA集合之Map >>HashMap/Hashtable/TreeMap/LinkedHashMap结构
Map 是一种键-值对(key-value)集合,键不可以重复,值可以重复。常见的实现类有:HashMap、Hashtable、TreeMap、LinkedHashMap等。 HashMap&Hashtable HashMap:数据结构为哈希表,允许使用 n…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
C++_哈希表
本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说,直接开始吧! 一、基础概念 1. 哈希核心思想: 哈希函数的作用:通过此函数建立一个Key与存储位置之间的映射关系。理想目标:实现…...
