证明java对象头偏向锁、轻量级锁、重量级锁以及其性能对比

1. 偏向锁:偏置锁模式用于使锁偏向给定的锁线程。当这个模式设置在低三位时,锁要么偏向某个特定的线程,要么是“匿名的”偏向,表明它可能是有偏见的。当锁是偏向于一个给定的线程,锁定和解锁可以在不使用原子操作的情况下由该线程执行。当锁的偏差被撤销时,它将恢复到正常状态下面描述的锁定方案。注意:Hotspot不会在JVM启动的最初几秒(目前是4秒)内启用偏向锁定对象。这是因为一些基准测试和NetBeans在启动时存在大量的线程争用,而且撤销成本非常高,可以在ieda设置关闭延迟启动 -XX:BiasedLockingStartupDelay=0 如下图,如果调用了计算hashcode()方法锁将会失去偏向线程特性。

2. 轻量级锁:轻量级锁是在单线程中或者多线程交替执行中没有锁竞争时候经过锁膨胀过程升级成为轻量级锁。得到cup 不需要调用os函数,调用jvm本身实现的锁函数。轻量级锁尝试在应用层面解决线程同步问题,而不触发操作系统互斥操作,轻量级锁减少多线程进入互斥几率,不能代替互斥,效率比偏向锁慢。

3. 重量级锁:在多线程竞争锁过程锁膨胀升级成为重量级锁,每次获取锁都调用os锁函数包括释放锁也同样调用os函数,性能比轻量级锁慢。如果调用wait()方法则锁立刻变成重量级锁。

一、首先我们需要知道什么是java对象头?

然后到jdk源码的hotpot(jvm)目录知道这个图 ,在markOop的源代码中有一个注释。openJdk源码(如果打不开可能需要vpn)。

各个锁的低3位标示

1、 意思是java的对象头在对象的不同状态下会有不同的表现形式,主要有三种状态,无锁状态、加锁状态、gc标记状 态。那么我可以理解ava当中的取锁其实可以理解是给对象上锁,也就是改变对象头的状态,如果上锁成功则进入同步代 码块。但是java当中的锁有分为很多种,从上图可以看出大体分为偏向锁、轻量锁、重量锁三种锁状态。这三种锁的效率完全不同、关于效率的分析会在下文分析,我们只有合理的设计代码,才能合理的利用锁、那么这三种锁的原理是什么? 所以我们需要先研究这个对象头

废话不多说上码:

* 引入依赖包

        <dependency>
            <groupId>org.openjdk.jol</groupId>
            <artifactId>jol-core</artifactId>
            <version>0.8</version>
        </dependency>
import org.openjdk.jol.info.ClassLayout;

import static java.lang.System.out;
public class JOLExample7 {
    static B b;
    public static void main(String[] args) throws Exception {
       // Thread.sleep(10000);
        b = new B();
        out.println("befre lock");
        out.println(ClassLayout.parseInstance(b).toPrintable());//无锁

        Thread t1= new Thread(){
            public void run() {
                synchronized (b){
                    try {
                        Thread.sleep(5000);
                        System.out.println("t1 release");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        t1.start();
        Thread.sleep(1000);
        out.println("t1 lock ing");
        out.println(ClassLayout.parseInstance(b).toPrintable());//轻量锁
        sync();
        out.println("after lock");
        out.println(ClassLayout.parseInstance(b).toPrintable());//重量锁

        System.gc();
        out.println("after gc()");
        out.println(ClassLayout.parseInstance(b).toPrintable());//重量锁---gc
    }

    public  static  void sync() throws InterruptedException {
        synchronized (b){
            System.out.println("t1 main lock");
            out.println(ClassLayout.parseInstance(b).toPrintable());//重量锁
        }
    }
}

public class B {

}

执行结果:

各个所性能对比博主不一一演示:偏向锁 > 轻量级锁  > 重量级锁

发布了16 篇原创文章 · 获赞 1 · 访问量 7344

猜你喜欢

转载自blog.csdn.net/broke_dr/article/details/103999840