synchoronized锁升级实践

对象内部结构

偏向锁:会把加锁线程的id(threadId 【54bit】)写入到对象头的mark word里面

对象结构说明

对象需先启用为偏向锁才能升级变为偏向锁,偏向锁不会主动释放

偏向锁->轻量级锁:有线程加锁,之后只要有其他线程来争锁,偏向锁立刻会升级为轻量级锁

轻量级锁->重量级锁:多个线程来竞争,当线程不断地CAS自旋都拿不到锁,达到一定自旋次数,才转化为重量级锁。

升级为重量级锁后,指针指向monitor

锁升级实践 

引入依赖

        <!--  帮助打印对象内部的组成结构-->
        <dependency>
            <groupId>org.openjdk.jol</groupId>
            <artifactId>jol-core</artifactId>
            <version>0.10</version>
        </dependency>
public class LockUpgrade {
    public static void main(String[] args) throws InterruptedException {
        User user = new User();
        System.out.println("无状态(001): "+ ClassLayout.parseInstance(user).toPrintable());

        /*java默认延时4s后自动开启偏向锁,可通过  -XX:BiasedLockingStarttupDelay=0 取消延时;
        如果不要偏向锁,可通过 -XX:-UseBisasedLocking = false 来设置
        **/
        Thread.sleep(5000); //为了开启偏向锁
        User user1 = new User();
        System.out.println("启用偏向锁(101): "+ ClassLayout.parseInstance(user1).toPrintable());

        for (int i = 0; i <2 ; i++) {
            synchronized (user1){
                System.out.println("偏向锁(101)(带线程id): "+ ClassLayout.parseInstance(user1).toPrintable());
            }
            System.out.println("偏向锁释放(101)(带线程id): "+ ClassLayout.parseInstance(user1).toPrintable());
        }
        new Thread( ()-> {
            synchronized (user1) {
                System.out.println("轻量级锁(00) : " + ClassLayout.parseInstance(user1).toPrintable());
                System.out.println("睡眠3秒钟===============");
                try {
                    Thread.sleep(3000);//目的是让 后面启动的线程过来 竞争锁  让轻量级锁变为重量级锁
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("轻量-->重量(10) : " + ClassLayout.parseInstance(user1).toPrintable());
            }
        }
        ).start();

        Thread.sleep(1000);//上面锁未释放,升级为重量级锁
        new Thread(()->{
            synchronized (user1){
                System.out.println("重量(10) : "+ ClassLayout.parseInstance(user1).toPrintable());
            }
        }).start();

    }
}

控制台打印情况

无状态(001): lock.User object internals:
 OFFSET  SIZE                TYPE DESCRIPTION                               VALUE
      0     4                     (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4                     (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4                     (object header)                           43 c1 00 20 (01000011 11000001 00000000 00100000) (536920387)
     12     4   java.lang.Integer User.id                                   null
     16     4    java.lang.String User.name                                 null
     20     4                     (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

启用偏向锁(101): lock.User object internals:
 OFFSET  SIZE                TYPE DESCRIPTION                               VALUE
      0     4                     (object header)                           05 00 00 00 (00000101 00000000 00000000 00000000) (5)
      4     4                     (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4                     (object header)                           43 c1 00 20 (01000011 11000001 00000000 00100000) (536920387)
     12     4   java.lang.Integer User.id                                   null
     16     4    java.lang.String User.name                                 null
     20     4                     (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

偏向锁(101)(带线程id): lock.User object internals:
 OFFSET  SIZE                TYPE DESCRIPTION                               VALUE
      0     4                     (object header)                           05 30 90 02 (00000101 00110000 10010000 00000010) (43003909)
      4     4                     (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4                     (object header)                           43 c1 00 20 (01000011 11000001 00000000 00100000) (536920387)
     12     4   java.lang.Integer User.id                                   null
     16     4    java.lang.String User.name                                 null
     20     4                     (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

偏向锁释放(101)(带线程id): lock.User object internals:
 OFFSET  SIZE                TYPE DESCRIPTION                               VALUE
      0     4                     (object header)                           05 30 90 02 (00000101 00110000 10010000 00000010) (43003909)
      4     4                     (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4                     (object header)                           43 c1 00 20 (01000011 11000001 00000000 00100000) (536920387)
     12     4   java.lang.Integer User.id                                   null
     16     4    java.lang.String User.name                                 null
     20     4                     (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

偏向锁(101)(带线程id): lock.User object internals:
 OFFSET  SIZE                TYPE DESCRIPTION                               VALUE
      0     4                     (object header)                           05 30 90 02 (00000101 00110000 10010000 00000010) (43003909)
      4     4                     (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4                     (object header)                           43 c1 00 20 (01000011 11000001 00000000 00100000) (536920387)
     12     4   java.lang.Integer User.id                                   null
     16     4    java.lang.String User.name                                 null
     20     4                     (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

偏向锁释放(101)(带线程id): lock.User object internals:
 OFFSET  SIZE                TYPE DESCRIPTION                               VALUE
      0     4                     (object header)                           05 30 90 02 (00000101 00110000 10010000 00000010) (43003909)
      4     4                     (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4                     (object header)                           43 c1 00 20 (01000011 11000001 00000000 00100000) (536920387)
     12     4   java.lang.Integer User.id                                   null
     16     4    java.lang.String User.name                                 null
     20     4                     (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

轻量级锁(00) : lock.User object internals:
 OFFSET  SIZE                TYPE DESCRIPTION                               VALUE
      0     4                     (object header)                           88 f2 f5 1a (10001000 11110010 11110101 00011010) (452326024)
      4     4                     (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4                     (object header)                           43 c1 00 20 (01000011 11000001 00000000 00100000) (536920387)
     12     4   java.lang.Integer User.id                                   null
     16     4    java.lang.String User.name                                 null
     20     4                     (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

睡眠3秒钟===============
轻量-->重量(10) : lock.User object internals:
 OFFSET  SIZE                TYPE DESCRIPTION                               VALUE
      0     4                     (object header)                           9a f5 90 17 (10011010 11110101 10010000 00010111) (395376026)
      4     4                     (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4                     (object header)                           43 c1 00 20 (01000011 11000001 00000000 00100000) (536920387)
     12     4   java.lang.Integer User.id                                   null
     16     4    java.lang.String User.name                                 null
     20     4                     (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

重量(10) : lock.User object internals:
 OFFSET  SIZE                TYPE DESCRIPTION                               VALUE
      0     4                     (object header)                           9a f5 90 17 (10011010 11110101 10010000 00010111) (395376026)
      4     4                     (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4                     (object header)                           43 c1 00 20 (01000011 11000001 00000000 00100000) (536920387)
     12     4   java.lang.Integer User.id                                   null
     16     4    java.lang.String User.name                                 null
     20     4                     (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total


Process finished with exit code 0

说明

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值