栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

测试synchronized的底层实现

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

测试synchronized的底层实现

测试synchronize的底层实现
    • 1、synchronized的三种应用方式
      • 1.1. 修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁
        • 修饰实例方法案例
        • 反编译结果分析(ACC_SYNCHRONIZED)
      • 1.2. 静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁
        • 修饰静态方法案例
        • 反编译结果分析(ACC_SYNCHRONIZED)
      • 1.3. 修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。
        • 修饰代码块案例
        • 反编译结果分析(monitorentermonitorexit)
          • monitorenter
          • monitorexit
          • 获取monitor的过程
      • 1.4 三种方式说明
    • 什么是monitor?
    • 参考链接

1、synchronized的三种应用方式 1.1. 修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁 修饰实例方法案例
public synchronized void print1() {
        System.out.println("Hello World");
    }
反编译结果分析(ACC_SYNCHRONIZED)

public synchronized void print1();
descriptor: ()V
flags: ACC_PUBLIC, ACC_SYNCHRONIZED
Code:
stack=2, locals=1, args_size=1
0: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #4 // String Hello World
5: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 10: 0
line 11: 8

说明:当方法被调用时,会检查ACC_SYNCHRONIZED标志是否被设置,若被设置,线程会先获取monitor,获取成功才能执行方法体,方法执行完成后会再次释放monitor。在方法执行期间,其他线程都无法获得同一个monitor对象。

1.2. 静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁 修饰静态方法案例
public static synchronized void print2() {
        System.out.println("Hello World");
    }
反编译结果分析(ACC_SYNCHRONIZED)
 public static synchronized void print2();
    descriptor: ()V
    flags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED
    Code:
      stack=2, locals=0, args_size=0
         0: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #4                  // String Hello World
         5: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
      LineNumberTable:
        line 14: 0
        line 15: 8
}

说明:当方法被调用时,会检查ACC_SYNCHRONIZED标志是否被设置,若被设置,线程会先获取monitor,获取成功才能执行方法体,方法执行完成后会再次释放monitor。在方法执行期间,其他线程都无法获得同一个monitor对象。

1.3. 修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。 修饰代码块案例
public class SynchTestDemo {
    public void print() {
        synchronized ("得物") {
            System.out.println("Hello World");
        }
    }
}
反编译结果分析(monitorentermonitorexit)
  public void print();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=3, args_size=1
         0: ldc           #2                  // String 得物
         2: dup
         3: astore_1
         4: monitorenter
         5: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
         8: ldc           #4                  // String Hello World
        10: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        13: aload_1
        14: monitorexit
        15: goto          23
        18: astore_2
        19: aload_1
        20: monitorexit
        21: aload_2
        22: athrow
        23: return

synchronized关键字被编译成字节码后会被翻译成monitorenter和monitorexit两条指令分别在同步块逻辑代码的起始位置与结束位置

monitorenter

任何一个对象都有一个monitor与其相关联,当且有一个monitor被持有后,它将处于锁定的状态,其他线程无法来获取该monitor。当JVM执行某个线程的某个方法内部的monitorenter时,他会尝试去获取当前对应的monitor的所有权

monitorexit

能执行monitorexit指令的线程一定是拥有当前对象的monitor的所有权的线程;

获取monitor的过程

如果monitor的进入数为0,则该线程进入monitor,然后将进入数设置为1,该线程即为monitor的所有者;
如果线程已经占有该monitor,只是重新进入,则进入monitor的进入数加1;
如果其他线程已经占用了monitor,则该线程进入阻塞状态,直到monitor的进入数为0,再重新尝试获取monitor的所有权;
执行monitorexit时会将monitor的进入数减1。当monitor的进入数减为0时,当前线程退出monitor,不再拥有monitor的所有权,此时其他被这个monitor阻塞的线程可以尝试去获取这个monitor的所有权;

1.4 三种方式说明
  1. synchronized修饰的实例方法和静态方式是通过 ACC_SYNCHRONIZED 标示符来实现加锁的。
  2. synchronized修饰的代码块是通过指令monitorenter和monitorexit来实现的。
  3. 上述同步方式从本质上看是没有区别的,两个指令的执行都是JVM调用操作系统的互斥原语mutex来实现的,被阻塞的线程会被挂起、等待重新调度,会导致线程在“用户态”和“内核态”进行切换,就会对性能有很大的影响。
什么是monitor?

monitor通常被描述为一个对象,可以将其理解为一个同步工具,或者可以理解为一种同步机制。所有的Java对象自打new出来的时候就自带了一把锁,就是monitor锁,也就是对象锁,存在于对象头(Mark Word),锁标识位为10,指针指向的是monitor对象起始地址。

参考链接

1)https://baijiahao.baidu.com/s?id=1713003848756478129&wfr=spider&for=pc&searchword=synchronized%E5%BA%95%E5%B1%82%E5%8E%9F%E7%90%86
2)https://www.cnblogs.com/wuzhenzhao/p/10250801.html

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/874405.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号