前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >synchronized 锁的升级过程

synchronized 锁的升级过程

作者头像
付威
发布2021-03-07 17:37:07
6490
发布2021-03-07 17:37:07
举报

测试代码

代码语言:javascript
复制
static A obj;
//	-XX:BiasedLockingStartupDelay=0  偏向锁开关
	// -XX:+PrintFlagsInitial 打印所有参数
	public static void main(String[] args) throws InterruptedException {
		obj = new A();
//		Thread.sleep(60000);
		System.out.println(ClassLayout.parseInstance(obj).toPrintable());
		printHeader();
//		obj.hashCode();
		printHeader();
		
		Thread thread = new Thread(() -> {
			printHeader();
		});
		Thread thread2 = new Thread(() -> {
			printHeader();
		});
		thread.start();
		thread2.start();
		thread.join();
		thread2.join();
	}
	
	private static void printHeader() {
		synchronized (obj) {
			System.out.println(ClassLayout.parseInstance(obj).toPrintable());
			System.out.println("========");
		}
		
	}

默认状态

1. 未加锁 ,锁状态是 001(无锁不可偏向)

代码语言:javascript
复制
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)                           47 c1 00 f8 (01000111 11000001 00000000 11111000) (-134168249)
    12     4        (loss due to the next object alignment)

2. 主线程进入,锁升级为 00(轻量级锁)

代码语言:javascript
复制
OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
     0     4        (object header)                           c0 f5 81 02 (11000000 11110101 10000001 00000010) (42071488)
     4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
     8     4        (object header)                           47 c1 00 f8 (01000111 11000001 00000000 11111000) (-134168249)
    12     4        (loss due to the next object alignment)

3. 线程 1 进入,无其他线程竞争 00

代码语言:javascript
复制
OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
     0     4        (object header)                           c0 f5 81 02 (11000000 11110101 10000001 00000010) (42071488)
     4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
     8     4        (object header)                           47 c1 00 f8 (01000111 11000001 00000000 11111000) (-134168249)
    12     4        (loss due to the next object alignment)

4. 线程 2 等线程 1 执行玩后进入,无其他线程竞争 00

代码语言:javascript
复制
OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
     0     4        (object header)                           38 f6 6c 1f (00111000 11110110 01101100 00011111) (527234616)
     4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
     8     4        (object header)                           47 c1 00 f8 (01000111 11000001 00000000 11111000) (-134168249)
    12     4        (loss due to the next object alignment)

5. 线程 1 和线程 2 同时进入 ,存在竞争 ,升级位重量级锁 10

代码语言:javascript
复制
OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           1a e7 ec 02 (00011010 11100111 11101100 00000010) (49080090)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           47 c1 00 f8 (01000111 11000001 00000000 11111000) (-134168249)
     12     4        (loss due to the next object alignment)

◆ 打开偏向锁开关

代码语言:javascript
复制
-XX:BiasedLockingStartupDelay=0 

1. 未加锁 锁状态 101,无锁可偏向,实际是偏向锁但是没有存储线程 ID,所以还是无锁状态

代码语言:javascript
复制
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)                           47 c1 00 f8 (01000111 11000001 00000000 11111000) (-134168249)
    12     4        (loss due to the next object alignment)

2. 主线程进入,锁状态 101,存储了线程 ID,转成真实的偏向锁。

代码语言:javascript
复制
OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
     0     4        (object header)                           05 40 41 03 (00000101 01000000 01000001 00000011) (54607877)
     4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
     8     4        (object header)                           47 c1 00 f8 (01000111 11000001 00000000 11111000) (-134168249)
    12     4        (loss due to the next object alignment)

3. 线程 1 进入,无其他线程竞争,锁状态 00 (轻量锁)

代码语言:javascript
复制
OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
     0     4        (object header)                           d8 f3 7e 1e (11011000 11110011 01111110 00011110) (511636440)
     4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
     8     4        (object header)                           47 c1 00 f8 (01000111 11000001 00000000 11111000) (-134168249)
    12     4        (loss due to the next object alignment)

4. 线程 2 进入,无其他线程竞争,锁状态 00 (轻量锁)

代码语言:javascript
复制
OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           a8 ef 7e 1e (10101000 11101111 01111110 00011110) (511635368)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           47 c1 00 f8 (01000111 11000001 00000000 11111000) (-134168249)
     12     4        (loss due to the next object alignment)

5. 线程 1 和线程 2 同时进入 ,存在竞争 10

代码语言:javascript
复制
OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
     0     4        (object header)                           5a e5 d1 02 (01011010 11100101 11010001 00000010) (47310170)
     4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
     8     4        (object header)                           47 c1 00 f8 (01000111 11000001 00000000 11111000) (-134168249)
    12     4        (loss due to the next object alignment)

◆ 打开偏向锁开关—-同时运行对象的HashCode

1. 未加锁 锁状态 101,无锁可偏向,实际是偏向锁但是没有存储线程 ID,所以还是无锁状态

代码语言:javascript
复制
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)                           47 c1 00 f8 (01000111 11000001 00000000 11111000) (-134168249)
    12     4        (loss due to the next object alignment)

2. 运行 hashcode 后,锁状态升级位无锁不可偏向 ,原本存放线程 ID 的位置被 hashcode 覆盖

代码语言:javascript
复制
OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           05 40 62 02 (00000101 01000000 01100010 00000010) (39993349)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           47 c1 00 f8 (01000111 11000001 00000000 11111000) (-134168249)
     12     4        (loss due to the next object alignment)

3. 线程 1 进入,无锁竞争,锁升级为轻量锁 000

代码语言:javascript
复制
OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
     0     4        (object header)                           90 f1 93 00 (10010000 11110001 10010011 00000000) (9695632)
     4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
     8     4        (object header)                           47 c1 00 f8 (01000111 11000001 00000000 11111000) (-134168249)
    12     4        (loss due to the next object alignment)

4. 线程 2 进入,存在锁竞争,锁升级为轻量锁 010

代码语言:javascript
复制
OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
     0     4        (object header)                           0a e5 71 02 (00001010 11100101 01110001 00000010) (41018634)
     4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
     8     4        (object header)                           47 c1 00 f8 (01000111 11000001 00000000 11111000) (-134168249)
    12     4        (loss due to the next object alignment)

◆ 锁升级基本流程

image-20210219230432521
image-20210219230432521
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-03-062,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 测试代码
  • 默认状态
    • 1. 未加锁 ,锁状态是 001(无锁不可偏向)
      • 2. 主线程进入,锁升级为 00(轻量级锁)
        • 3. 线程 1 进入,无其他线程竞争 00
          • 4. 线程 2 等线程 1 执行玩后进入,无其他线程竞争 00
            • 5. 线程 1 和线程 2 同时进入 ,存在竞争 ,升级位重量级锁 10
            • ◆ 打开偏向锁开关
              • 1. 未加锁 锁状态 101,无锁可偏向,实际是偏向锁但是没有存储线程 ID,所以还是无锁状态
                • 2. 主线程进入,锁状态 101,存储了线程 ID,转成真实的偏向锁。
                  • 3. 线程 1 进入,无其他线程竞争,锁状态 00 (轻量锁)
                    • 4. 线程 2 进入,无其他线程竞争,锁状态 00 (轻量锁)
                      • 5. 线程 1 和线程 2 同时进入 ,存在竞争 10
                      • ◆ 打开偏向锁开关—-同时运行对象的HashCode
                        • 1. 未加锁 锁状态 101,无锁可偏向,实际是偏向锁但是没有存储线程 ID,所以还是无锁状态
                          • 2. 运行 hashcode 后,锁状态升级位无锁不可偏向 ,原本存放线程 ID 的位置被 hashcode 覆盖
                            • 3. 线程 1 进入,无锁竞争,锁升级为轻量锁 000
                              • 4. 线程 2 进入,存在锁竞争,锁升级为轻量锁 010
                                • ◆ 锁升级基本流程
                                相关产品与服务
                                对象存储
                                对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
                                领券
                                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档