synchronized 的 monitor 机制
synchronized 的 monitor 机制
前言
- 本文基于 jdk 8 编写。
- @author JellyfishMIX - github / blog.jellyfishmix.com
- LICENSE GPL-2.0
monitor
-
monitor 是 synchronized 中用以实现线程之间的互斥与协作的主要手段,它可以看成是对象或者 class 持有的锁。每一个对象有且仅有一个 monitor。
-
这也是为什么会看到 synchronized(object) 或 synchronized(MainActivity.class) 这样的写法,这样指明了使用了什么对象或类持有的 monitor。
-
下图描述了线程和 monitor之间关系,以及线程的状态转换图。

-
如上图,每个 monitor 在每个时刻,只能被一个线程持有,该线程就是 activeThread,其它线程都是 waitingThread,分别在两个队列 entrySet 和 waitSet 里等候。在 entrySet 中等待的线程状态是 waiting for monitor entry,而在 wait set 中等待的线程状态是 in Object.wait()。
entrySet
-
先看 entrySet 里面的线程。我们称被 synchronized 包起来的代码段为临界区。
synchronized(object) {// ...... } -
当一个线程尝试进入临界区时,有两种可能性:
-
该 monitor 不被其它线程持有,entrySet 里面也没有其它等待线程。尝试获取 monitor 的当前线程即成为对应对象或类的 monitor 的 owner,执行临界区的代码。
-
该 monitor 被其它线程拥有,尝试获取 monitor 的当前线程在 entrySet 队列中等待并休眠。
-
第一种情况下,线程将处于 Runnable 的状态。第二种情况下,线程 dump 输出信息会显示处于 waiting for monitor entry。如下:
"Thread-0" prio=10 tid=0x08222eb0 nid=0x9 waiting for monitor entry [0xf927b000..0xf927bdb8] at testthread.WaitThread.run(WaitThread.java:39) - waiting to lock <0xef63bf08> (a java.lang.Object) - locked <0xef63beb8> (a java.util.ArrayList) at java.lang.Thread.run(Thread.java:595)
-
-
临界区的机制,是为了保证其内部代码执行的原子性,消除竞态条件。
-
需要注意的是,临界区在任何时间只允许线程串行通过,这和我们使用多线程提高性能的初衷是相反的。如果在多线程的程序中,大量使用 synchronized,或者不恰当地使用了它,会造成大量线程在临界区的入口等待获取 monitor,造成性能大幅下降。通过 dump 排查问题时,这也是要排查的点。
-
排查线程阻塞的问题时,cpu 忙则关注 Runnable 的线程,可能正在运行的线程数量太多了,比如线程池 coreSize 设置的太大了。cpu 闲则关注 dump 输出信息中的 waiting for monitor entry,可能大量线程阻塞在获取 monitor。只有获得了 monitor 的线程在占用 cpu 时间片运行,cpu 利用率低。
waitSet
-
当线程获得了 monitor,进入临界区之后,如果代码编写调用了 monitor 对应的对象(一般是被 synchronized 修饰的对象)的 wait() 方法,此时放弃 monitor,进入 waitSet 队列并休眠。
-
只有别的线程在该对象上调用了 notify() 或 notifyAll() 方法,waitSet 队列中线程才得到机会去竞争。但是只有一个线程能获得此对象的 monitor,线程状态恢复到 Runnable,其他线程继续在 waitSet 中等待并休眠。
-
在 waitSet 中的线程,dump 输出信息中表现为: in Object.wait()。
"Thread-1" prio=10 tid=0x08223250 nid=0xa in Object.wait() [0xef47a000..0xef47aa38] at java.lang.Object.wait(Native Method) - waiting on <0xef63beb8> (a java.util.ArrayList) at java.lang.Object.wait(Object.java:474) at testthread.MyWaitThread.run(MyWaitThread.java:40) - locked <0xef63beb8> (a java.util.ArrayList) at java.lang.Thread.run(Thread.java:595)
synchronized 的锁升级机制(偏向锁, 轻量级锁, 重量级锁)
entrySet 的机制被称为重量级锁,性能较差。jdk 1.6 从 JVM 层⾯对 synchronized 进行了⼤优化,引入了偏向锁, 轻量级锁和锁升级机制,提高了 synchronized 的性能。
偏向锁
- ObjectHeader 对象头信息中,有一个标记记录了此对象 monitor 的持有线程,如果尝试获取的线程和此对象 monitor 的持有线程相同,则直接获得 monitor,不需要走锁机制。体现了 synchronized 可重入锁的特征。
轻量级锁
- 当一个线程尝试进入临界区时,如果获取偏转锁失败,则进行轻量级锁的机制,CAS 自旋尝试抢锁。
- 这个设计是为了提高锁的性能,如果在 CAS 自旋期间抢到了锁,则可以减少线程休眠和苏醒的开销。
重量级锁
- 自旋 n 次(默认为10,可以通过 JVM 参数 PreBlockSpin 调整) 如果仍未抢到,则升级为重量级锁,线程进入 entrySet。entrySet 的机制如本文前部分所述。
相关文章:
synchronized 的 monitor 机制
synchronized 的 monitor 机制 前言 本文基于 jdk 8 编写。author JellyfishMIX - github / blog.jellyfishmix.comLICENSE GPL-2.0 monitor monitor 是 synchronized 中用以实现线程之间的互斥与协作的主要手段,它可以看成是对象或者 class 持有的锁。每一个对象…...
NumPy 初学者指南中文第三版:1~5
原文:NumPy: Beginner’s Guide - Third Edition 协议:CC BY-NC-SA 4.0 译者:飞龙 一、NumPy 快速入门 让我们开始吧。 我们将在不同的操作系统上安装 NumPy 和相关软件,并看一些使用 NumPy 的简单代码。 本章简要介绍了 IPython…...
ChatGLM-6B论文代码笔记
ChatGLM-6B 文章目录 ChatGLM-6B前言一、原理1.1 优势1.2 实验1.3 特点:1.4 相关知识点 二、实验2.1 环境基础2.2 构建环境2.3 安装依赖2.4 运行2.5 数据2.6 构建前端页面 3 总结 前言 Github:https://github.com/THUDM/ChatGLM-6B 参考链接:…...
机器学习入门实例-加州房价预测-1(数据准备与可视化)
问题描述 数据来源:California Housing Prices dataset from the StatLib repository,1990年加州的统计数据。 要求:预测任意一个街区的房价中位数 缩小问题:superwised multiple regressiong(用到人口、收入等特征) univariat…...
【ROS2指南-20】了解ROS2组件的用法
在单个进程中组合多个节点 目录 背景 运行演示 发现可用组件 使用 ROS 服务 (1.) 与发布者和订阅者的运行时组合 使用 ROS 服务 (1.) 与服务器和客户端的运行时组合 使用 ROS 服务的编译时组合 (2.) 使用 dlopen 的运行时组合 使用启动动作组合 高级主题 卸载组件 重新…...
使用AI进行“文本纠错”
AI在现实中的应用有很多,你有没有想过,它还可以进行文本纠错呢?传统的校对既耗时又枯燥,通过“AI纠错”,不仅能更快完成,还能提高准确度。那么AI“文本纠错”背后的原理是什么呢?和我一起看看吧…...
第九章 法律责任与法律制裁
第九章 法律责任与法律制裁_副本 目录 第一节 法律责任的概念 一 法律责任的含义二 法律责任的特点 第二节 法律责任的分类与竞合 一 法律责任的分类 (一)根据责任行为所违反的法律的性质 民事责任:刑事责任行政责任违宪责任 (二…...
如何选择好用的海康视频恢复软件?综合考虑这几点
海康视频恢复通常是指从海康威视监控设备中恢复删除或丢失的视频。在使用海康设备进行监控时,一些重要的视频可能会被误删除或其他原因导致丢失,如果没有及时备份,数据就可能会“永久”丢失?其实不然,我们可以选择好用…...
前端学习:HTML颜色(什么是RGB、HEX、HSL)
一、什么是RGB、HEX、HSL? 无论是RGB、HEX、HSL,它们的作用只有一个:用数字表达出一种颜色。 1.RGB RGB通过输入的数值,将红色、绿色和蓝色的光源以一定的量混合在一起,形成颜色。 软件中通常让你输入Red、Green、B…...
zookeeper + kafka集群搭建详解
目录 1.消息队列介绍 1.为什么需要消息队列 (MO) 2.使用消息队列的好处 3.消息队列的两种模式 2.Kafka相关介绍 1.Kafka定义 2.Kafka简介 3. Kafka的特性 3.Kafka系统架构 1. Broker(服务器) 2. Topic(一个队…...
【数据结构与算法】 - 双向链表 - 详细实现思路及代码
目录 一、概述 二、双向链表 三、双向链表实现步骤 📌3.1 C语言定义双向链表结点 📌3.2 双向链表初始化 📌3.3 双向链表插入数据 📌3.4 双向链表删除数据 📌3.5 双向链表查找数据 📌3.6 双向链…...
面试官在线点评4份留学生简历! 这些坑你中了几个?如何写项目描述才能被大厂发面试?转专业简历该咋写 | 还有优秀简历展示!
我们给大家展示一下 从材料的准备 也就是说到底包含哪些具体的项目 为什么说这些项目是不错的 第二呢就是说在陈述上 在整个这个简历的结构 他的完备性他的准确性 他的正确性 以及最后他的具体的这种项目的描述 那讲完了这个好的简历呢 我们另外搜集了几份简历 那这些简历呢其实…...
一觉醒后ChatGPT 被淘汰了
OpenAI 的 Andrej Karpathy 都大力宣传,认为 AutoGPT 是 prompt 工程的下一个前沿。 近日,AI 界貌似出现了一种新的趋势:自主人工智能。 这不是空穴来风,最近一个名为 AutoGPT 的研究开始走进大众视野。特斯拉前 AI 总监、刚刚回归…...
spring框架的事务
1.什么是事务? 事务:是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作;这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行;事务是一组不可再分割的操作集合(工作逻辑单元…...
Spring配置数据源
Spring配置数据源数据源的作用环境准备手动创建c3p0数据源封装抽取关键信息,手动创建c3p0数据源使用Spring容器配置数据源数据源的作用 数据源(连接池)是提高程序性能如出现的 事先实例化数据源,初始化部分连接资源 使用连接资源时从数据源中获取 使用完…...
【前端之旅】Vue入门笔记
一名软件工程专业学生的前端之旅,记录自己对三件套(HTML、CSS、JavaScript)、Jquery、Ajax、Axios、Bootstrap、Node.js、Vue、小程序开发(Uniapp)以及各种UI组件库、前端框架的学习。 【前端之旅】Web基础与开发工具 【前端之旅】手把手教你安装VS Code并附上超实用插件…...
WPF教程(二)--Application WPF程序启动方式
1.Application介绍 WPF与WinForm一样有一个 Application对象来进行一些全局的行为和操作,并且每个 Domain (应用程序域)中仅且只有一个 Application 实例存在。和 WinForm 不同的是WPF Application默认由两部分组成 : App.xaml 和 App.xaml.…...
snmp 自定义子代理mib库
测试环境:centos8 1、安装软件 yum install -y net-snmp net-snmp-utils yum install -y net-snmp-perl net-snmp-devel net-snmp-libs 2、创建用户 net-snmp-create-v3-user 输入用户名 soft 输入密码 123456 输入密码 654321 service snmpd restart 3、创建…...
一文说透安全沙箱技术
在数字经济的东风中,数据安全至关重要。目前已经颁布了包括《数据安全法》、《个人信息保护法》和《数据安全管理办法》在内的国家政策,以促进整个数据要素的发展。 而近年来,随着移动应用程序的普及和小程序技术的崛起,安全沙箱…...
Java多线程基础面试总结(二)
创建三种线程的方式对比 使用实现Runnable、Callable接口的方式创建多线程。 优势 Java的设计是单继承的设计,如果使用继承Thread的方式实现多线程,则不能继承其他的类,而如果使用实现Runnable接口或Callable接口的方式实现多线程…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
