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接口的方式实现多线程…...

NS32F407VGT6 NS32F407VET6软硬件通用STM32F407VGT6 407VET6
NS32F407VGT6 NS32F407VET6 器件基于高性能的 ARM Cortex-M4 32 位 RISC 内核,工作频率高达 168MHz 。 Cortex-M4 内核带有单精度浮点运算单元 (FPU) ,支持所有 ARM 单精度数据处理指令和数据类型。它还 具有一组 DSP 指令和提高应用安全性的一…...

Openstack: network: ovs: dpif/show 实例分析:interface
[TOC 实例 [cbis-adminovercloud–13 (overcloudrc) ~]$ sudo ovs-appctl dpif/show systemovs-system: hit:75198007884 missed:109924265 br-ex: br-ex 65534/3: (internal) ,65534 是port number; OpenFlow port number; 3 是 ofp_port_to_odp_port(ofproto, o…...

必要的项目管理软件因素
什么样的项目管理软件好?对于一个项目团队来说,从项目开始到项目结束,需要多个部门的配合。每个成员可能会参与一个以上的项目,这通常需要并行的多个项目。据介绍,国外90%以上的项目是用软件管理的,而中国只…...

大学刚毕业,用10000小时,走进字节跳动拿了offer
前言: 没有绝对的天才,只有持续不断的付出。对于我们每一个平凡人来说,改变命运只能依靠努力幸运,但如果你不够幸运,那就只能拉高努力的占比。 2020年7月,我有幸成为了字节跳动的一名测试开发,…...

docker 安装 redis
搜索镜像 docker search redis 拉取最新版本 Docker pull redis Docker挂载配置文件 docker run --restartalways --log-opt max-size100m --log-opt max-file2 -p 6379:6379 --name myredis -v /opt/myredis/redis.conf:/etc/redis/redis.conf -v /opt/myredis/data:/d…...

Ceph常见问题
1. CephFS问题诊断 1.1 无法创建 创建新CephFS报错Error EINVAL: pool ‘rbd-ssd’ already contains some objects. Use an empty pool instead,解决办法: ceph fs new cephfs rbd-ssd rbd-hdd --force1.2 mds.0 is damaged 断电后出现此问题。MDS进…...

Android---Jetpack之Paging
目录 Paging 组件的意思 Paging 支持的架构类型 Paging 的工作原理 PositionalDataSource PagekeyedDataSource ItemKeyedDataSource BoundaryCallback Paging 组件的意思 分页加载是在应用程序开发过程中十分常见的需求,Paging 就是 Google 为了方便 Andr…...

gensim.models.word2vec() 参数详解
1. Word2vec简介 Word2vec是一个用来产生词向量的模型。是一个将单词转换成向量形式的工具。 通过转换,可以把对文本内容的处理简化为向量空间中的向量运算,计算出向量空间上的相似度,来表示文本语义上的相似度。 2.Word2vec参数详解 class…...

光栅和矢量图像处理SDK:Graphics Mill 11.7Crack
Graphics Mill 是适用于 .NET 和 ASP.NET 开发人员的最强大的成像工具集。它允许用户轻松地向 .NET 应用程序添加复杂的光栅和矢量图像处理功能。 光栅图形 加载和保存 JPEG、PNG PSD 和其他 8 种图像格式 调整大小、裁剪、自动修复、色度键和 30 多种其他图像处理 使用任何维度…...

阿里云的客服 锻炼你心性的 一种方式 !!!
阿里云的产品,非常棒,开发的同学非常棒,专家们更棒,但,一切的开始就怕一个但字,但我还的说,但,阿里云的客服,OMG ,我已经忍耐了 1年了,是在忍不住…...