为什么在静态方法和类中同步会得到不同的Java字节码。

huangapple go评论68阅读模式
英文:

Why synchronized in static method and in Class get different java byte code

问题

以下是翻译好的部分:

我已经学到,静态方法和类中的 synchronized 关键字是相同的,它们都是类级别的锁。

然后我尝试编写一个示例程序:

package com.hao.thread;

public class Main {
    private static int count = 10;

    public synchronized static void m1() {
        --count;
        System.out.println(Thread.currentThread().getName() + " count = " + count);
    }

    public static void m2() {
        synchronized (Main.class) {
            --count;
            System.out.println(Thread.currentThread().getName() + " count = " + count);
        }
    }

    public static void main(String[] args) {

    }
}

编译后,使用 jclasslib(一个 IntelliJ IDEA 插件)检查 Java 字节码,我发现 m1()m2() 的字节码是不同的,m1() 方法的字节码中没有 monitorenter

以下是图片链接,由于我声望不足,只能粘贴图片的直接链接:

  • m1() 的 Java 字节码:m1
  • m2() 的 Java 字节码:m2

我想知道为什么会出现这种情况?而且有了不同的 Java 字节码,它们如何拥有相同的行为?JVM 是否为我做了额外的处理?

英文:

I have learned that synchronized in static method and Class are the same thing, they are both class level lock.

Then I try to write a demo program:

package com.hao.thread;

public class Main {
    private static int count = 10;

    public synchronized static void m1() {
        --count;
        System.out.println(Thread.currentThread().getName() + " count = " + count);
    }

    public static void m2() {
        synchronized (Main.class) {
            --count;
            System.out.println(Thread.currentThread().getName() + " count = " + count);
        }
    }

    public static void main(String[] args) {

    }
}

After compile, and check the java bytecode with jclasslib(a idea plugin), I found m1() and m2() got different java bytecode, there is no monitorenter in the bytecode of m1() method.

the pictures are follows, because I don't have enough reputation, I have to paste the direct link of image

  • m1() java bytecode: ![m1](https://i.stack.imgur.com/QRzJ5.jpg)
  • m2() java bytecode: ![m2](https://i.stack.imgur.com/yrTvJ.jpg)

I wonder why it happen? And with the different java bytecode, how can they have the same behaviour? Is there any extra thing JVM done for me?

答案1

得分: 0

参见 JVM 规范 §17.1 - 虚拟机会看到 'synchronized' 关键字,并隐式执行 monitorenter。在 Java 字节码中,有两种获取对象锁的方式:通过 synchronized 关键字或通过 MONITORENTER 字节码,就是这么简单。

英文:

See JVM Specification §17.1 - the VM sees the 'synchronized' keyword and does the monitorenter implicitly. There are 2 ways to obtain the lock on an object in java bytecode: Either via a synchronized keyword, or via a MONITORENTER bytecode, it's as simple as that.

huangapple
  • 本文由 发表于 2020年9月8日 09:11:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/63785898.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定