JUC并发编程 -- JIT即时编译器之锁清除

Posted Z && Y

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JUC并发编程 -- JIT即时编译器之锁清除相关的知识,希望对你有一定的参考价值。

1.1 锁消除

导入相关依赖:

因为 JMH 是 JDK9 自带的,如果是 JDK9 之前的版本需要加入如下依赖

        <dependency>
            <groupId>org.openjdk.jmh</groupId>
            <artifactId>jmh-core</artifactId>
            <version>1.23</version>
        </dependency>
        <dependency>
            <groupId>org.openjdk.jmh</groupId>
            <artifactId>jmh-generator-annprocess</artifactId>
            <version>1.23</version>
        </dependency>

示例代码:

package com.tian;
import org.openjdk.jmh.annotations.*;

import java.util.concurrent.TimeUnit;

@Fork(1)
// 统计程序运行的平均时间
@BenchmarkMode(Mode.AverageTime)
// 以纳秒为单位
@OutputTimeUnit(TimeUnit.NANOSECONDS)
// 预热3次 让代码的运行环境得到优化 得到最真实的运行时间
@Warmup(iterations = 3)
// 测试5轮
@Measurement(iterations = 5)
public class MyBenchmark {
    static int x = 0;

    @Benchmark
    public void a() throws Exception {
        x++;
    }

    @Benchmark
    // JIT即时编译器
    public void b() throws Exception {
        Object o = new Object();
        synchronized (o) {
            x++;
        }
    }
}

打成jar包:

运行jar包:

在target目录打开控制台输入:
java -jar jar包名

运行结果:

为什么一个加了锁一个没有加锁运行效率还是差不多呢?

Java是一个解释+编译的执行方式,对Java中的代码是解释执行,但是对于对于反复调用的代码会使用JIT即时编译器进行进一步的优化。优化的其中七个手段就是看局部变量可不可以优化,这里发现b()方法中的o变量没有逃离方法的作用范围,也没有暴露引用,所以o变量不可能被共享,所以对o加锁没有任何意义,所以JIT即时编译器会把这里的synchronized关键字直接优化掉,真正这个代码执行时其实是没有synchronized的,所以上面代码的执行效率是差不多的

关闭锁消除运行刚刚的jar包:

在target目录打开控制台输入:
java -XX:-EliminateLocks -jar jar包名



以上是关于JUC并发编程 -- JIT即时编译器之锁清除的主要内容,如果未能解决你的问题,请参考以下文章

CUDA 表达式模板和即时编译 (JIT)

『GCTT 出品』使用 Go 语言写一个即时编译器(JIT)

浅析 JIT 即时编译技术

如何获得即时编译器(JIT)的汇编代码(linux环境下)

jit即时编译

jit即时编译