java静态方法 同步_java静态同步方法底层实现?

题主问的是HotSpot VM的具体实现的问题。

根据JVM规范的规定,Java的静态方法如果被标注为synchronized(既同时带有 ACC_STATIC 与 ACC_SYNCHRONIZED 修饰符),则要锁的是该静态方法所在的类对应的 java.lang.Class 实例。

具体到HotSpot VM的实现,对于一个Java类,假如说有:

class Foo {

synchronized static void bar() { }

}

则我们要明确一下概念:

Foo obj = new Foo();

Class> clz = obj.getClass();

assert(clz == Foo.class);

Class> clzClz = clz.getClass();

assert(clzClz == Class.class);

这里,new Foo() 会创建一个 Foo 类的对象实例;obj 是一个执行该新建实例的引用。通过 obj.getClass() 可以获得该实例的运行时类对应的 java.lang.Class 类的对象实例。java.lang.Class 自身也是一个类,它自然也有自己对应的 java.lang.Class 类的实例。

HotSpot VM所实现的对象模型里,Java对象有对象头,里面有两个字段:_mark:记录该对象实例的各种状态信息;

_klass:一个指向该对象的运行时类的 Klass 内部对象的指针

然后这个 Klass 内部对象是HotSpot VM内部用来记录类的元数据的内部对象,并不对Java程序直接暴露出来。在这个上下文里,它里面有两个有趣的东西:一个是 _java_mirror 字段,指向该类对应的 java.lang.Class 对象;另一个是 prototype_header ,记录着该类的所有实例都会拥有的某些初始状态。例如说biased locking就会利用prototype header机制来控制某个Java类是否要参与biased locking——把prototype header设置为不带有biased pattern的值的情况下,这个类就不参与biased locking。

由 Klass::_java_mirror 字段指向的 java.lang.Class 对象就是暴露给Java程序的对应物。HotSpot VM并不通过它来记录类的元数据,只是通过它暴露一些Java / JVM规范说要提供给Java程序的反射信息。Java的静态方法锁的就是这个对象。

举个例子。用Oracle JDK9来跑以下实验:

class Foo {

synchronized static void bar() { }

}

public class Demo {

public static void main(String[] args) throws Exception {

Foo obj = new Foo();

Class> clz = obj.getClass();

System.in.read();

}

}

跑起来之后,用JDK9自带的jhsdb命令来启动图形化的HSDB(HotSpot Debugger)工具:

这里,左上的小窗口是线程列表。中间上方的小窗口是main线程的栈内存,我特意把它移动到了让 Demo.main() 方法的栈帧在正中间的位置,可以看到 Demo.main() 方法的参数/局部变量就在里面(ObjArray、Foo、java/lang/Class那三个便是)。

下方的两个小窗口是Inspector,用来查看对象数据。左边的是 Foo 类对应的 InstanceKlass,右边的是 java.lang.Class 类对应的 InstanceMirrorKlass。可以看到,Foo 类对应的 InstanceKlass 中的 _java_mirror 字段的值跟我们通过 obj.getClass() 得到的引用是一摸一样的。

同时也可以看到,这两个 Klass 里的 _prototype_header 的值都是 5 ,这就是 bias_pattern ,也就是说 biased locking 对这两个类目前都是开启的。

Foo.bar() 方法是静态的而且声明为 synchronized,其执行语义其实等价于:

class Foo {

static void bar() {

synchronized (Foo.class) {

}

}

}

只要 biased locking 对 java.lang.Class 类开启,java.lang.Class 类的实例在被锁的时候就会尝试走 biased locking 路径。这里正是这样的情况。没啥特别的。

希望以上能解答题主的疑惑。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值