JVM 内置锁 synchronized 关键字,偏向锁优化中的批量重偏向和批量撤销(下)

简介: JVM 内置锁 synchronized 关键字,偏向锁优化中的批量重偏向和批量撤销

批量偏向锁撤销


当撤销偏向锁的阈值超过 40 次过后, jvm  会认为不该偏向,于是整个类的所有对象都会变成不可偏向,新创建的对象也不可偏向。 注意:  对于统计批量撤销有个参数:-XX:BiasedLockingDecayTime=25000ms范围内没有达到 40 次,撤销次数清 0 ,重新记时


public class B1 {
    public static void main(String[] args) throws Exception {
        Thread.sleep(5000);
        List<A> listA = new ArrayList<>();
        Thread t1 = new Thread(() -> {
            for (int i = 0; i <100 ; i++) {
                A a = new A();
                synchronized (a){
                    listA.add(a);
                }
            }
            try {
                Thread.sleep(100000000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t1.start();
        Thread.sleep(3000);
        Thread t2 = new Thread(() -> {
            //这里循环了40次。达到了批量撤销的阈值
            for (int i = 0; i < 40; i++) {
                A a =listA.get(i);
                synchronized (a){
                }
            }
            try {
                Thread.sleep(10000000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t2.start();
        Thread.sleep(3000);
        System.out.println("打印list中第11个对象的对象头:");
        System.out.println((ClassLayout.parseInstance(listA.get(10)).toPrintable()));
        System.out.println("打印list中第26个对象的对象头:");
        System.out.println((ClassLayout.parseInstance(listA.get(25)).toPrintable()));
        System.out.println("打印list中第90个对象的对象头:");
        System.out.println((ClassLayout.parseInstance(listA.get(89)).toPrintable()));
        Thread t3 = new Thread(() -> {
            for (int i = 20; i < 40; i++) {
                A a =listA.get(i);
                synchronized (a){
                    if(i==20||i==22){
                        System.out.println("thread3 第"+ i + "次");
                        System.out.println((ClassLayout.parseInstance(a).toPrintable()));
                    }
                }
            }
        });
        t3.start();
        Thread.sleep(10000);
        System.out.println("重新输出新实例A");
        System.out.println((ClassLayout.parseInstance(new A()).toPrintable()));
    }
}


看看输出结果,这部分和上面的批量偏向有些不同。重点关注线程 id

前 20 个对象并没有触发批量重偏向机制,线程 t2 释放锁之后,变成无锁状态;

第 20 - 40 个对象,触发了批量重偏向机制,对象为偏向锁状态,偏向线程 t2, 线程 t2 的 id 为 -1005618939


第 41 个对象之后,也没有触发了批量重偏向机制,对象依然偏向线程 t1 , 线程 t1  的 id 是  -1039208443


image.png


t3 线程开始进行锁的竞争,因为已经到到批量撤销的阈值,且对象  listA.get(20) 和 listA.get(22) 已经进行了锁的重偏向了,所以 t3 再次获取锁的时候,不会触发重新偏向为线程 t3.


此刻,触发批量撤销,此对象碰撞变为轻量级锁


image.png


最后我们看一下新生成的对象。本来应该是可偏向状态,但是在经历过批量重偏向,和批量撤销之后转换为无锁。


image.png


批量重偏向和批量撤销总结


  • 批量重偏向和批量撤销针对类的优化,和对象无关。


  • 批量锁重新偏向一次过后不能重新偏向。


  • 当某个类已经触发批量撤销机制后, JVM 会默认当前类长生了严重的问题,剥夺了该类新生成对象偏向锁的权利。


参考资料






相关文章
|
1月前
|
存储 安全 Java
jvm 锁的 膨胀过程?锁内存怎么变化的
【10月更文挑战第3天】在Java虚拟机(JVM)中,`synchronized`关键字用于实现同步,确保多个线程在访问共享资源时的一致性和线程安全。JVM对`synchronized`进行了优化,以适应不同的竞争场景,这种优化主要体现在锁的膨胀过程,即从偏向锁到轻量级锁,再到重量级锁的转变。下面我们将详细介绍这一过程以及锁在内存中的变化。
37 4
|
4月前
|
缓存 安全 算法
Java面试题:如何通过JVM参数调整GC行为以优化应用性能?如何使用synchronized和volatile关键字解决并发问题?如何使用ConcurrentHashMap实现线程安全的缓存?
Java面试题:如何通过JVM参数调整GC行为以优化应用性能?如何使用synchronized和volatile关键字解决并发问题?如何使用ConcurrentHashMap实现线程安全的缓存?
45 0
|
1月前
|
Arthas 监控 Java
JVM知识体系学习七:了解JVM常用命令行参数、GC日志详解、调优三大方面(JVM规划和预调优、优化JVM环境、JVM运行出现的各种问题)、Arthas
这篇文章全面介绍了JVM的命令行参数、GC日志分析以及性能调优的各个方面,包括监控工具使用和实际案例分析。
43 3
|
1月前
|
存储 算法 Java
深入理解Java虚拟机(JVM)及其优化策略
【10月更文挑战第10天】深入理解Java虚拟机(JVM)及其优化策略
41 1
|
1月前
|
存储 安全 Java
JVM锁的膨胀过程与锁内存变化解析
在Java虚拟机(JVM)中,锁机制是确保多线程环境下数据一致性和线程安全的重要手段。随着线程对共享资源的竞争程度不同,JVM中的锁会经历从低级到高级的膨胀过程,以适应不同的并发场景。本文将深入探讨JVM锁的膨胀过程,以及锁在内存中的变化。
40 1
|
1月前
|
监控 Java
Java的JVM如何优化?
Java的JVM如何优化?
56 3
|
1月前
|
存储 Kubernetes 架构师
阿里面试:JVM 锁内存 是怎么变化的? JVM 锁的膨胀过程 ?
尼恩,一位经验丰富的40岁老架构师,通过其读者交流群分享了一系列关于JVM锁的深度解析,包括偏向锁、轻量级锁、自旋锁和重量级锁的概念、内存结构变化及锁膨胀流程。这些内容不仅帮助群内的小伙伴们顺利通过了多家一线互联网企业的面试,还整理成了《尼恩Java面试宝典》等技术资料,助力更多开发者提升技术水平,实现职业逆袭。尼恩强调,掌握这些核心知识点不仅能提高面试成功率,还能在实际工作中更好地应对高并发场景下的性能优化问题。
|
4月前
|
缓存 Prometheus 监控
Java面试题:如何监控和优化JVM的内存使用?详细讲解内存调优的几种方法
Java面试题:如何监控和优化JVM的内存使用?详细讲解内存调优的几种方法
94 3
|
4月前
|
监控 Java 中间件
FGC频繁导致CPU 飙升定位及JVM配置优化总结
FGC频繁导致CPU 飙升定位及JVM配置优化总结
160 0
|
4月前
|
存储 缓存 安全
Java面试题:介绍一下jvm中的内存模型?说明volatile关键字的作用,以及它如何保证可见性和有序性。
Java面试题:介绍一下jvm中的内存模型?说明volatile关键字的作用,以及它如何保证可见性和有序性。
36 0