zoukankan      html  css  js  c++  java
  • JIT对锁的优化- 锁消除和锁粗化案例分析

    锁消除和锁粗化案例分析

    锁消除

    • 直接上代码
    /**
     * 描述:  锁粒度演示
     * @author karl
     * @create 2020-02-11 14:38
     */
    public class MySynchronizedTest07 {
        private Object object = new Object();
    
    
        public void method() {
            synchronized (object) {
                System.out.println("hello  world");
            }
        }
    
    }
    
    • 上述是一个简单的同步代码块的案例,在并发的情况下多个线程是共享MySynchronizedTest07 的成员变量 object所以才达到了锁的效果。
    • 我们再看下面一个案例代码:
    package com.karl.concurrent.syn;
    
    /**
     * 描述:  锁粒度演示
     *
     * @author karl
     * @create 2020-02-11pw 14:38
     */
    public class MySynchronizedTest07 {
    
        public void method() {
            Object object = new Object();
            synchronized (object) {
                System.out.println("hello  world");
            }
        }
    }
    
    • 上述代码我们可知将object变成了局部变量,在方法中,方法的的局部变量时线程独立的,并发的场景每个线程都有各自的object对象,这个时候的锁就无意义的。
    • 我们在编译上述代码的时候其实也发现了monitorenter和monitorexit,在字节码层面看上去还有有锁的获取和释放。
    • 这个时候JIT编译器可以在动态编译同步代码的时候,使用一种叫做逃逸分析的技术(后续学习jvm的时候会涉及到),来通过该技术判断程序中使用的锁对象是否只被一个线程所使用。而没有别的线程进行竞争。当这种情况的下,那么JIT编译器在编译(将字节码编程机器码)这个同步代码时就不会生成synchronized关键字所标识锁的申请和释放的机器码。从而消除锁的使用流程。这就是锁消除的原理和案例。

    锁粗化

    • 直接上代码:
    
    /**
     * 描述:  锁粗化
     *
     * @author karl
     * @create 2020-02-11 15:15
     */
    public class MySynchronizedTest08 {
    
        private Object object = new Object();
    
    
        public void method() {
            synchronized (object) {
                System.out.println("hello");
            }
    
            synchronized (object) {
                System.out.println("world");
            }
    
            synchronized (object) {
                System.out.println("!");
            }
        }
    }
    
    • 代码很简单,在这里就不用做代码解释了
    • 我们直接看JIt编译器如何优化上述代码的。
    • JIT编译器在执行动态编译的时候。若发现前后相邻的synchronized块使用的是同一个锁对象,那么它就会把这几个synchronized块合并成一个较大的同步快,这样做的好处在于线程执行这些代码的时候,就无需频繁申请和释放锁了,从而达到申请与释放一次就可以执行全部的同步代码块,从而提高了性能。

    总结

    • 由于JIT编译后的是机器码,不能实际的去操作相应的优化效果。所以先理解理论即可。
  • 相关阅读:
    java-connect-mysql
    搜索框提示列表问题
    方法中的函数会掩盖this,解决办法!
    关于W3C盒子布局
    将类数组转化成数组
    js获取元素宽高
    使用gulp添加版本号
    flex布局
    排序-冒泡排序
    js事件、自定义dom事件、自定义事件
  • 原文地址:https://www.cnblogs.com/karlMa/p/12295244.html
Copyright © 2011-2022 走看看