Mismo código de bytes para el método con o sin la palabra clave sincronizada de firma del método

dkb:

Durante los 2 siguientes clases tiene el mismo código de bytes de Java.

versión de Java:

java version "1.8.0_181" Java (TM) SE Runtime Environment (build 1.8.0_181-b13) Java HotSpot (TM) de 64 bits del servidor VM (build-b13 25.181, de modo mixto)

javac y la versión javap:

1.8.0_181

Mi duda es

  1. No debería método con el sincronizado de palabras clave tienen diferente código de bytes, como podemos ver en el bloque sincronizado tiene monitorentery monitorexit, o supongamos que no hay que mezclar bloque sincronizado y método sincronizado a continuación,

  2. ¿Cómo JVM manejar ambos métodos de manera diferente?

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

    y

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

Código de bytes de la siguiente manera:

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

Bytecodes para los archivos respectivos:

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
}

y

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
}

Sólo quiero aumentar mi comprensión de código de bytes de Java WRT.

Avisadme como comentarios si mi enfoque es erróneo o si una pregunta es demasiado trivial.

Cualquier referencia a la documentación relacionada, es muy positivo, excepto lo siguiente:

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

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

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

Yole:

El synchronizedmodificador en el método se compila en la bandera ACC_SYNCHRONIZED en la cabecera del método. No afecta a las instrucciones de código de bytes generados; el código para entrar y salir se añade el monitor de forma implícita por la JVM cuando ve que la bandera.

Ver la especificación de JVM para la lista completa de banderas en la cabecera del método y su significado.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=225166&siteId=1
Recomendado
Clasificación