Тот же байт-код для метода с или без синхронизированного ключевого слова в сигнатуре метода - PullRequest
0 голосов
/ 19 октября 2018

Для следующих 2 классов получен один и тот же байт-код Java.

java версия:

java версия "1.8.0_181" Java (TM) SE Runtime Environment (сборка 1.8.0_181-b13) Виртуальная 64-битная виртуальная машина Java HotSpot (TM) (сборка 25.181-b13, смешанный режим)

версия javac и javap:

1.8.0_181

Я сомневаюсь, что

  1. не должен метод с synchronized ключевое слово имеет другой байт-код, как мы видим в синхронизированном блоке имеет monitorenter и monitorexit, или давайте предположим, что я не должен смешивать синхронизированный блок и синхронизированный метод затем

  2. КакJVM обрабатывает оба метода по-разному?

    public class MySingleton1 {
    
    private MySingleton1() {}
    
    private static MySingleton1 ourInstance;
    
    public static MySingleton1 getInstance() {
        if (ourInstance == null) {
            ourInstance = new MySingleton1();
        }
        return ourInstance;
    }
    }
    

    и

    public class MySingleton2 {
    
    private MySingleton2() {}
    
    private static MySingleton2 ourInstance;
    
    public static synchronized MySingleton2 getInstance() {
        if (ourInstance == null) {
            ourInstance = new MySingleton2();
        }
        return ourInstance;
    }
    }
    

Байт-код выглядит следующим образом:

$javac MySingleton1.java
$javap -c MySingleton1
$javac MySingleton2.java
$javap -c MySingleton2

Байт-коды для соответствующих файлов:

Compiled from "MySingleton1.java"
public class MySingleton1 {
  public static MySingleton1 getInstance();
    descriptor: ()LMySingleton1;
    Code:
       0: getstatic     #2                  // Field ourInstance:LMySingleton1;
       3: ifnonnull     16
       6: new           #3                  // class MySingleton1
       9: dup
      10: invokespecial #4                  // Method "<init>":()V
      13: putstatic     #2                  // Field ourInstance:LMySingleton1;
      16: getstatic     #2                  // Field ourInstance:LMySingleton1;
      19: areturn
}

и

Compiled from "MySingleton2.java"
public class MySingleton2 {
  public static synchronized MySingleton2 getInstance();
    descriptor: ()LMySingleton2;
    Code:
       0: getstatic     #2                  // Field ourInstance:LMySingleton2;
       3: ifnonnull     16
       6: new           #3                  // class MySingleton2
       9: dup
      10: invokespecial #4                  // Method "<init>":()V
      13: putstatic     #2                  // Field ourInstance:LMySingleton2;
      16: getstatic     #2                  // Field ourInstance:LMySingleton2;
      19: areturn
}

Я просто хочу улучшить свое понимание java wrt bytecode.

Дайте мне знать в качестве комментариев, если мой подход неверен oЕсли вопрос слишком тривиальный.

Любая ссылка на документацию приветствуется, за исключением следующих:

https://en.wikipedia.org/wiki/Java_bytecode

https://en.wikipedia.org/wiki/Java_bytecode_instruction_listings

http://www.cnblogs.com/richaaaard/p/6214929.html

1 Ответ

0 голосов
/ 19 октября 2018

Модификатор synchronized в методе компилируется в флаг ACC_SYNCHRONIZED в заголовке метода.Это не влияет на сгенерированные инструкции байт-кода;код для входа и выхода из монитора неявно добавляется JVM, когда он видит этот флаг.

Полный список флагов в заголовке метода и их значение см. в спецификации JVM .

...