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即时编译器之锁清除的主要内容,如果未能解决你的问题,请参考以下文章