锁撤销阈值达到20次批量重偏向是针对类还是线程?撤销阈值达到20次触发的20是指撤销偏向锁20次后触发还是19次后触发?

先说答案, 锁的批量重偏向是针对类的,且只能触发一次,撤销阈值20次是指撤销19个对象偏向锁后再来一个对象需要撤销才会触发锁的批量重偏向,实际会撤销19个。

测试过程如下:

建立spring项目,要有依赖

        <dependency>
            <groupId>org.openjdk.jol</groupId>
            <artifactId>jol-core</artifactId>
            <version>0.16</version> 
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

 测试一

package com.itheima.mybatis;

import lombok.extern.slf4j.Slf4j;
import org.openjdk.jol.info.ClassLayout;

import java.util.Vector;
import java.util.concurrent.locks.LockSupport;

/**
 * @author 名
 * @date 2024/8/2-18:44
 */
@Slf4j
public class Test4 {
    public static void main(String[] args) throws InterruptedException {
        Test4.test4();
    }

    static Thread t1, t2, t3;

    private static void test4() throws InterruptedException {
        Vector<Dog> list = new Vector<>();
        int loopNumber = 60 ;
        t1 = new Thread(() -> {
            for (int i = 0; i < loopNumber; i++) {
                Dog d = new Dog();
                list.add(d);
                synchronized (d) {
                    log.debug(i+1 + "号" + ClassLayout.parseInstance(d).toPrintable());
                }
            }
            LockSupport.unpark(t2);
        }, "t1");
        t1.start();
        t2 = new Thread(() -> {
            LockSupport.park();
            log.debug("===============> ");
            for (int i = 0; i < loopNumber; i++) {
                Dog d = list.get(i);
                synchronized (d) {
                    log.debug(i+1 + "号" + ClassLayout.parseInstance(d).toPrintable());
                }
            }
            LockSupport.unpark(t3);
        }, "t2");
        t2.start();
        t3 = new Thread(() -> {
            LockSupport.park();
            log.debug("===============> ");
            for (int i = 0; i < loopNumber; i++) {
                Dog d = list.get(i);
                synchronized (d) {
                    log.debug(i+1 + "号" + ClassLayout.parseInstance(d).toPrintable());
                }
            }
        }, "t3");
        t3.start();


    }

}
class Dog{}

线程t1建立60个对象,并让60个对象加锁(偏向锁偏向t1),线程t2,t3分别对60个对象加锁,多线程执行顺序为t1->t2->t3。

测式结果:

可以看到结果,t2撤销19个偏向锁后(1号至19号),第20次触发批量重偏向,而t3在第20次没有触发批量重偏向,说明撤销阈值20是针对类的不是针对线程的,且只能触发一次。

测是二:

package com.itheima.mybatis;

import lombok.extern.slf4j.Slf4j;
import org.openjdk.jol.info.ClassLayout;

import java.util.Vector;
import java.util.concurrent.locks.LockSupport;

/**
 * @author 名
 * @date 2024/8/2-18:44
 */
@Slf4j
public class Test4 {
    public static void main(String[] args) throws InterruptedException {
        Test4.test4();
    }

    static Thread t1, t2, t3;

    private static void test4() throws InterruptedException {
        Vector<Dog> list = new Vector<>();
        int loopNumber = 29 ;
        t1 = new Thread(() -> {
            for (int i = 0; i < loopNumber; i++) {
                Dog d = new Dog();
                list.add(d);
                synchronized (d) {
                    log.debug(i+1 + "号" + ClassLayout.parseInstance(d).toPrintable());
                }
            }
            LockSupport.unpark(t2);
        }, "t1");
        t1.start();
        t2 = new Thread(() -> {
            LockSupport.park();
            log.debug("===============> ");
            for (int i = 0; i < loopNumber-10; i++) {
                Dog d = list.get(i);
                synchronized (d) {
                    log.debug(i+1 + "号" + ClassLayout.parseInstance(d).toPrintable());
                }
            }
            LockSupport.unpark(t3);
        }, "t2");
        t2.start();
        t3 = new Thread(() -> {
            LockSupport.park();
            log.debug("===============> ");
            for (int i = 0; i < loopNumber; i++) {
                Dog d = list.get(i);
                synchronized (d) {
                    log.debug(i+1 + "号" + ClassLayout.parseInstance(d).toPrintable());
                }
            }
        }, "t3");
        t3.start();


    }

}
class Dog{}

修改数值,线程t1建立29个对象,并让29个对象加锁(偏向锁偏向t1),线程t2对前19个对象加锁,t3对29个对象加锁,多线程执行顺序为t1->t2->t3。

可以看到线程t2撤销前19个,但因为没有第20个对象,所以没有触发批量重偏向,二线程t3因为有第20个对象加锁所以触发批量重偏向,说明撤销偏向锁19次后,不会触发批量重偏向,只有第20个对象需要变更偏向才会触发批量重偏向。

参考资料:【黑马程序员深入学习Java并发编程,JUC并发编程全套教程-哔哩哔哩】 https://b23.tv/dt4w9la

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值