对jvm 同步锁的理解
sychronized是jvm中对线程同步的主要方法和机制。
Thread.sleep是让线程丢掉cpu分配资源(让调度器在某时间内不再调度该线程)。
一个对象的锁只能同时被一个线程所持有。
对于每一个线程都是两个ObjectMinor list,一个是freelist,一个是usedlist;usedlist是该线程占有那些对象的锁,一个线程可以占有多个对象的锁。
jvm ObjectMinor源代码:
ObjectMonitor() {_header = NULL;//markOop对象头_count = 0;_waiters = 0,//等待线程数_recursions = 0;//重入次数_object = NULL;//监视器锁寄生的对象。锁不是平白出现的,而是寄托存储于对象中。_owner = NULL;//指向获得ObjectMonitor对象的线程或基础锁_WaitSet = NULL;//处于wait状态的线程,会被加入到wait set;_WaitSetLock = 0 ;_Responsible = NULL ;_succ = NULL ;_cxq = NULL ;FreeNext = NULL ;_EntryList = NULL ;//处于等待锁block状态的线程,会被加入到entry set;_SpinFreq = 0 ;_SpinClock = 0 ;OwnerIsThread = 0 ;// _owner is (Thread *) vs SP/BasicLock_previous_owner_tid = 0;// 监视器前一个拥有者线程的ID}
object notify() 随意获取(之前调用wait而阻塞的线程)一个线程唤醒去执行,但是去执行不一定是直接获取这个对象的锁,或者执行这个对象中方法,只是唤醒而已。但是注意:去执行object.notify的线程必须是获取该对象object的锁的线程,否则会爆出IllegalMonitorStateException。因为只有持有该对象的锁,该线程中的minor usedlist才有该对象的objectminor,才有能力获取该objectminor中的_WaitSet 等待队列。
对于ObjectMinor中EntrySet存放的阻塞block队列,我们是没有办法直接唤醒的.
每个object都包含markOop。如下图所示:
class oopDesc {friend class VMStructs;private:volatile markOop _mark;//markOop:Mark Word标记字段union _metadata {Klass* _klass;//对象类型元数据的指针narrowKlass _compressed_klass;} _metadata;// Fast access to barrier set. Must be initialized.static BarrierSet* _bs;public:markOop mark() const { return _mark; }markOop* mark_addr() const { return (markOop*) &_mark; }void set_mark(volatile markOop m) { _mark = m; }void release_set_mark(markOop m);markOop cas_set_mark(markOop new_mark, markOop old_mark);// Used only to re-initialize the mark word (e.g., of promoted// objects during a GC) -- requires a valid klass pointervoid init_mark();Klass* klass() const;Klass* klass_or_null() const volatile;Klass** klass_addr();narrowKlass* compressed_klass_addr();}
oopDesc --继承--> markOopDesc --方法monitor()--> ObjectMonitor-->enter、exit 获取、释放锁
markOopDesc类
openjdk\hotspot\src\share\vm\oops\markOop.hpp下markOopDesc继承自oopDesc,并拓展了自己的方法monitor(),如下图
ObjectMonitor* monitor() const {assert(has_monitor(), "check");// Use xor instead of &~ to provide one extra tag-bit check.return (ObjectMonitor*) (value() ^ monitor_value);}
说说EntrySet和waitSet队列:
(1)所有期待获得锁的线程,在锁已经被其它线程拥有的时候,这些期待获得锁的线程就进入了Object Lock的entry set区域。
(2)所有曾经获得过锁,但是由于其它必要条件不满足而需要wait的时候,线程就进入了Object Lock的wait set区域 。
(3)在wait set区域的线程获得Notify/notifyAll通知的时候,随机的一个Thread(Notify)或者是全部的Thread(NotifyALL)从Object Lock的wait set区域进入了entry set中。
(4)在当前拥有锁的线程释放掉锁的时候,处于该Object Lock的entryset区域的线程都会抢占该锁,但是只能有任意的一个Thread能取得该锁,而其他线程依然在entry set中等待下次来抢占到锁之后再执行。
当获取当前锁的线程离开同步区,对象的锁值减一,且锁值为0(锁可以重复进入,每次进入自加1),那么监视器会释放信息量,Entry_set队列中的线程会抢锁,只有一个线程可以获取锁。
对jvm 同步锁的理解相关推荐
- 理解悲观锁乐观锁、同步锁、读锁、写锁
ava 锁分类 Java 中的锁有很多,可以按照不同的功能.种类进行分类,下面是我对 Java 中一些常用锁的分类,包括一些基本的概述 从线程是否需要对资源加锁可以分为 悲观锁 和 乐观锁 从资源已被 ...
- 面试官:你了解JVM的锁优化吗?
本文分享自百度开发者中心面试官:你了解JVM的锁优化吗? 锁优化.md 文章已同步至 GitHub 开源项目: JVM 底层原理解析 高效并发是 JDK5 升级到 JDK6 后一项重要的改进,Hot ...
- 存储过程没有执行完后没有释放锁_【大厂面试07期】说一说你对synchronized锁的理解?...
PS:本文已收录到1.3 K+ Star 数的开源项目-<大厂面试指北>,如果想要了解更多,可以看一看,项目地址如下: https://github.com/NotFound9/inter ...
- 垃圾回收算法与实现系列-JVM无锁实现
导语 为了确保多线程场景下数据安全,使用锁机制一直是一种优秀的解决方案,但是再高并发场景下,对锁的竞争可能成为性能瓶颈.为此,有出现了一种新的解决方案,被称为是非阻塞同步的方案.这种实现方式不需要 ...
- JVM内部锁升级过程(偏向锁,轻量级锁,重量级锁)
目录 对象在内存中是如何布局的 如何查看对象在内存中的布局 markword数据结构 加锁后发生了什么 偏向锁 什么是偏向锁 偏向锁定时hashCode 哪去了? 为什么需要偏向锁 为什么从JDK15 ...
- 并发编程之原子性及同步锁
并发编程之同步锁 一.概述 对之前写的Synchronized详解补充. 如果多个线程在做同一件事情的时候,会出现安全性问题: 原子性 Synchronized, AtomicXXX.Lock 可见性 ...
- 【245期】面试官:同类中两个方法加同步锁,多个线程支持同时访问这两个方法吗?...
点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方有惊喜,留言必回,有问必答! 每天 08:15 更新文章,每天进步一点点... ...
- 黑马毕向东Java课程笔记(day11):多线程(第一部分)——进程与线程+线程创建+线程安全与同步代码块+同步锁/死锁
多线程好文:添加链接描述 锁机制:synchronized.Lock.Condition.volatile(原子性可见性)--参考添加链接描述 1.进程与线程概述 首先,对于CPU执行每一个程序, ...
- 字节二面 —— 什么是同步锁、死锁、乐观锁、悲观锁
马上就要到金三银四佳季了,是找工作的好时候,小伙伴们一定要把握好时机,找到心仪的高薪工作.找工作就少不了面试,那我们从现在开始,多刷刷面试题,查缺补漏!!! 目录 1. 面向对象的特征 2. Java ...
最新文章
- 应用市场自然量预估_VIVO市场ASO实战详解
- c语言 字符转int型,C语言—类型之间的转换
- 微信WeixinJSBridge API
- VScode 透明背景设置
- C语言嵌入式系统编程修炼之内存操作
- python.集合转列表_Python列表、元组、字典、集合
- 实验三lr1分析法java_第十讲 频域分析法(Nyquist曲线)
- Java神鬼莫测之Mybatis--增删改查CRUD以及批量操作(二)
- C语言俄罗斯方块代码
- 解决MySQL报错[Err] 1093 - You can't specify target...
- React使用iconfont阿里巴巴矢量图库
- 骁龙7c+ Gen 3评测怎么样
- 工业相机的曝光方式:全局曝光、卷帘曝光、全局复位释放曝光区别
- xmos固件u8_有福啦~XMOS固件更新啦~
- iBatis对SQL语句的解析。
- 【u3d泰斗破坏神】08 --- UGUI 制作艺术字体
- JS实现图片下载功能
- 合规羊毛党小贴士,谈谈award caculator
- 正则表达式判断手机号码格式是否合法
- Pon De Replay【MMD动作+镜头下载】
热门文章
- django-oscar-paypal出现UnicodeEncodeError: 'latin-1' codec can't encode characters in position XXXX
- App.vue文件報錯
- wine运行bat文件
- java.lang.UnsatisfiedLinkError: org.apache.hadoop.util.NativeCrc32.nativeComputeChunkedSumsByteArray
- 数据库原理 简单基础入门
- Eclipse配置自动提示(eclipse设置代码API自动出现)
- ORA-12170:TNS:连接超时
- ConcurrentHashMap的实现原理和源码分析
- Shader学习笔记_函数探索_tex2D(sampler2D tex, float2 s)
- 学习笔记900天总结