zoukankan      html  css  js  c++  java
  • 深入理解synchronized

    加锁原理

      synchronized (a){} 锁住的就是()里面的对象,多个线程对同一个对象操作时,就会形成互斥效果,如果是操作两个不同的对象,那么就不会受synchronized影响。

    public class SynchronizedDemo {
        public static void main(String[] args) {
            SynchronizedDemo s = new SynchronizedDemo();
            Integer a = 1;
            Integer b = 2;
    
            new Thread(()->{
                s.sync(a);
            }).start();
            new Thread(()->{
                s.sync(b);
                //s.sync(a);
            }).start();
        }
    
        public void sync(Integer a){
            synchronized (a){
                System.out.println("线程:"+Thread.currentThread().getName()+" 获取到变量"+a);
                try {
                    Thread.sleep(8000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    在jdk中,synchronized同步是基于Monitor对象实现的,它里面主要有两个指令:
      monitorenter: 插入到同步代码块的开始位置
      monitorexit: 插入到同步代码块结束的位置
    它们对应着JMM模型8大原子操作的lock与unlock,lock获取锁后把对象加载到工作内存,数据操作完之后重新赋值到主内存,最后unlock解锁。JVM需要保证每一个monitorenter都有一个monitorexit与之对应。为了保证在方法异常时,monitorenter和monitorexit指令也能正常配对执行,编译器会自动产生一个异常处理器,它的目的就是用来执行 异常的monitorexit指令。通过monitor里的加锁计数器可以实现可重入的加锁。 Monitor(监视器锁)是依赖操作系统的Mutex Lock(互斥锁)实现的,需要向内核申请资源,此时cpu将由用户态转换为内核态,它是一个低性能重量级锁。

    synchronized优化

      jdk1.6之后就对这个synchronized锁进行了各种优化,是基于 jvm 通过 cas 设置头信息来做的。如适应性自旋锁、轻量级锁和偏向锁,并默认开启偏向锁。从 无锁—>偏向锁—>轻量级锁—>重量级锁 ,锁升级的这个过程是不可逆的。被加锁的对象 jvm中为它定义了一种对应的数据结构,通过判断数据结构的对象头就知道目前是什么锁状态。例如通过倒数第三个bit的值 0/1 就知道目前是无锁还是偏向锁了。

    三种锁的区别

      偏向锁:仅有一个线程进入临界区(主要用于不存在锁竞争,而是一个线程多次获得锁时,为的使线程获取锁使用最小的代价(因为只需要修改获取锁的线程id就好了))
      轻量级锁:多个线程交替进入临界区(当其他线程尝试竞争偏向锁时,会升级为轻量锁)
      重量级锁:多个线程同时进入临界区

    锁的升级过程

    1. 无锁:此时还没有线程获取所得资源

      

     2. 获取偏向锁:第一个线程获取到锁就会将前面的23个bit位修改为自己线程的id,将无锁升级为偏向锁。

       

     3. 升级轻量锁:此时另一个线程尝试获取锁,发现锁里的线程id并不是自己的,就会释放锁,将对象头重的Mark Word替换为指向锁记录的指针,将其升级为轻量锁。

      

    4. 若刚才将对象头重的Mark Word替换为指向锁记录的指针失败,则会自旋(循环等待)来获取锁,此时若有另一个线程同时竞争,锁会升级为重量级锁。

       

  • 相关阅读:
    redis全面解析
    SoapUI Pro Project Solution Collection-change the JDBC Request behavior
    SoapUI Pro Project Solution Collection-Test Step Object
    SoapUI Pro Project Solution Collection-access the soapui object
    SoapUI Pro Project Solution Collection –Easy develop Groovy Script to improve SoapUI ability
    Eclipse 个人使用配置
    Selenium 致命杀手(有关自动化的通病)
    Open-Source performance testing tools(From other site)
    麦当劳理论(转转转)
    java command line error opening registry key 'SoftwareJavaSoftJava Runtime Environment' java.dll
  • 原文地址:https://www.cnblogs.com/wlwl/p/15004431.html
Copyright © 2011-2022 走看看