zoukankan      html  css  js  c++  java
  • Synchronized的锁升级过程(无锁->偏向锁->轻量级锁->重量级锁)

    1>当一个对象被创建存储在内存里边会涉及到一个对象头,里边有一块区域叫mark word,会保存一个无锁的状态。在一个线程访问到被synchronized修饰的代码块时,会将该线程的id保存到到mark world相应的区域,同时更改锁的状态为偏向锁。

    2>当出现了锁竞争的情况下,会看下当前线程还持有该锁不,若没有,就重新上偏向锁,若还是持有偏向锁,就将偏向锁转化为轻量级锁,并且这种锁的升级是不可逆的。因为这种转化会stop the world,因此对于一些多线程场景较多的应用,可以设置jvm参数,让应用不使用偏向锁。

    3>轻量级锁有两种:自旋锁,自适应自旋锁。对于自旋锁就是一个线程正持有该锁,另外一个线程进来了就等着,相当于执行一个循环,只到成功获取到了锁。但是循环是要消耗资源的,不可能让线程在那一直循环,就设置了一个固定的循环次数10,超过了10回就认为你获取不到该锁了,执行下一步操作,比如升级成重量级锁。对于自适应自旋锁,没有固定的循环次数,而是对于每个锁有一个学习能力,就是说对于某个锁,一个线程循环了5次拿到了,那么下一个线程也循环5次去获取这个锁,获取不到,就直接转成重量级锁。

    4>重量级锁是通过一个监视器锁对象monitor实现的,monitor随着对象的创建而创建。线程获取锁可以理解为获取monitor,成功之后会对monitor对象加一,释放掉了就减一。这种加一减一实际上是通过操作系统的mutex(互斥)、lock实现的。操作系统实现mutexlock需要从用户态转换成核心态,成本比较大,耗费时间长。这就是synchronized效率低的原因。1.6之前,synchronized主要是依靠操作系统的mutexlock指令,比较耗费资源,之后引入了偏向锁和轻量级锁的概念,提高了效率,这也是1.8中,concurrenthashmap使用synchronized锁的原因。

  • 相关阅读:
    QT解析和组装json
    linux下磁盘存储空间不足
    linux下的QT打包方法
    linux下编译protobuf
    linux下编译opencv
    linux下的qt串口通信
    QT执行shell脚本及linux指令相关
    windows下QT打包
    启动zookeeper却没有进程
    Linux命令
  • 原文地址:https://www.cnblogs.com/20158424-hxlz/p/13961865.html
Copyright © 2011-2022 走看看