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 同步锁的理解相关推荐

  1. 理解悲观锁乐观锁、同步锁、读锁、写锁

    ava 锁分类 Java 中的锁有很多,可以按照不同的功能.种类进行分类,下面是我对 Java 中一些常用锁的分类,包括一些基本的概述 从线程是否需要对资源加锁可以分为 悲观锁 和 乐观锁 从资源已被 ...

  2. 面试官:你了解JVM的锁优化吗?

    本文分享自百度开发者中心面试官:你了解JVM的锁优化吗? 锁优化.md 文章已同步至 GitHub 开源项目: JVM 底层原理解析 ​高效并发是 JDK5 升级到 JDK6 后一项重要的改进,Hot ...

  3. 存储过程没有执行完后没有释放锁_【大厂面试07期】说一说你对synchronized锁的理解?...

    PS:本文已收录到1.3 K+ Star 数的开源项目-<大厂面试指北>,如果想要了解更多,可以看一看,项目地址如下: https://github.com/NotFound9/inter ...

  4. 垃圾回收算法与实现系列-JVM无锁实现

    导语   为了确保多线程场景下数据安全,使用锁机制一直是一种优秀的解决方案,但是再高并发场景下,对锁的竞争可能成为性能瓶颈.为此,有出现了一种新的解决方案,被称为是非阻塞同步的方案.这种实现方式不需要 ...

  5. JVM内部锁升级过程(偏向锁,轻量级锁,重量级锁)

    目录 对象在内存中是如何布局的 如何查看对象在内存中的布局 markword数据结构 加锁后发生了什么 偏向锁 什么是偏向锁 偏向锁定时hashCode 哪去了? 为什么需要偏向锁 为什么从JDK15 ...

  6. 并发编程之原子性及同步锁

    并发编程之同步锁 一.概述 对之前写的Synchronized详解补充. 如果多个线程在做同一件事情的时候,会出现安全性问题: 原子性 Synchronized, AtomicXXX.Lock 可见性 ...

  7. 【245期】面试官:同类中两个方法加同步锁,多个线程支持同时访问这两个方法吗?...

    点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方有惊喜,留言必回,有问必答! 每天 08:15 更新文章,每天进步一点点... ...

  8. 黑马毕向东Java课程笔记(day11):多线程(第一部分)——进程与线程+线程创建+线程安全与同步代码块+同步锁/死锁

    多线程好文:添加链接描述 锁机制:synchronized.Lock.Condition.volatile(原子性可见性)--参考添加链接描述 1.进程与线程概述   首先,对于CPU执行每一个程序, ...

  9. 字节二面 —— 什么是同步锁、死锁、乐观锁、悲观锁

    马上就要到金三银四佳季了,是找工作的好时候,小伙伴们一定要把握好时机,找到心仪的高薪工作.找工作就少不了面试,那我们从现在开始,多刷刷面试题,查缺补漏!!! 目录 1. 面向对象的特征 2. Java ...

最新文章

  1. 应用市场自然量预估_VIVO市场ASO实战详解
  2. c语言 字符转int型,C语言—类型之间的转换
  3. 微信WeixinJSBridge API
  4. VScode 透明背景设置
  5. C语言嵌入式系统编程修炼之内存操作
  6. python.集合转列表_Python列表、元组、字典、集合
  7. 实验三lr1分析法java_第十讲 频域分析法(Nyquist曲线)
  8. Java神鬼莫测之Mybatis--增删改查CRUD以及批量操作(二)
  9. C语言俄罗斯方块代码
  10. 解决MySQL报错[Err] 1093 - You can't specify target...
  11. React使用iconfont阿里巴巴矢量图库
  12. 骁龙7c+ Gen 3评测怎么样
  13. 工业相机的曝光方式:全局曝光、卷帘曝光、全局复位释放曝光区别
  14. xmos固件u8_有福啦~XMOS固件更新啦~
  15. iBatis对SQL语句的解析。
  16. 【u3d泰斗破坏神】08 --- UGUI 制作艺术字体
  17. JS实现图片下载功能
  18. 合规羊毛党小贴士,谈谈award caculator
  19. 正则表达式判断手机号码格式是否合法
  20. Pon De Replay【MMD动作+镜头下载】

热门文章

  1. django-oscar-paypal出现UnicodeEncodeError: 'latin-1' codec can't encode characters in position XXXX
  2. App.vue文件報錯
  3. wine运行bat文件
  4. java.lang.UnsatisfiedLinkError: org.apache.hadoop.util.NativeCrc32.nativeComputeChunkedSumsByteArray
  5. 数据库原理 简单基础入门
  6. Eclipse配置自动提示(eclipse设置代码API自动出现)
  7. ORA-12170:TNS:连接超时
  8. ConcurrentHashMap的实现原理和源码分析
  9. Shader学习笔记_函数探索_tex2D(sampler2D tex, float2 s)
  10. 学习笔记900天总结