2011-10-05 13 views
5

tengo la clase siguiente:diferencias entre los métodos de JVM no sincronizadas sincronizados y

public class SeqGenerator { 

    int last = 0; 
    volatile int lastVolatile = 0; 

    public int getNext() { 
     return last++; 
    } 

    public synchronized int getNextSync() { 
     return last++; 
    } 

    public int getNextVolatile() { 
     return lastVolatile++; 
    } 

    public void caller() { 
     int i1 = getNext(); 
     int i2 = getNextSync(); 
     int i3 = getNextVolatile(); 
    } 

} 

Cuando miro el código desensamblado no veo la diferencia entre la representación de los tres métodos getNext(), getNextSync() y getNextVolatile() .

public int getNext(); 
    Code: 
    0: aload_0 
    1: dup 
    2: getfield #2; //Field last:I 
    5: dup_x1 
    6: iconst_1 
    7: iadd 
    8: putfield #2; //Field last:I 
    11: ireturn 

public synchronized int getNextSync(); 
    Code: 
    0: aload_0 
    1: dup 
    2: getfield #2; //Field last:I 
    5: dup_x1 
    6: iconst_1 
    7: iadd 
    8: putfield #2; //Field last:I 
    11: ireturn 

public int getNextVolatile(); 
    Code: 
    0: aload_0 
    1: dup 
    2: getfield #3; //Field lastVolatile:I 
    5: dup_x1 
    6: iconst_1 
    7: iadd 
    8: putfield #3; //Field lastVolatile:I 
    11: ireturn 

public void caller(); 
    Code: 
    0: aload_0 
    1: invokevirtual #4; //Method getNext:()I 
    4: istore_1 
    5: aload_0 
    6: invokevirtual #5; //Method getNextSync:()I 
    9: istore_2 
    10: aload_0 
    11: invokevirtual #6; //Method getNextVolatile:()I 
    14: istore_3 
    15: return 

¿Cómo el JMV puede distinguir entre estos métodos?

El código generado es el mismo de estos métodos y también de sus llamadores. ¿Cómo realiza la JVM la sincronización?

Respuesta

6

La palabra clave synchronized aplicada a un método solo establece el indicador ACC_SYNCHRONIZED en esa definición de método, como se define en the JVM specification § 4.6 Methods. No será visible en el bytecode real del método.

El JLS § 8.4.3.6 synchronized Methods discute la similitud de la definición de un método synchronized y declarando un bloque synchronized que se extiende por todo el cuerpo del método (y con el mismo objeto para sincronizar en): la efecto es exactamente el mismo, pero que están representados de manera diferente en el archivo .class.

Un efecto similar ocurre con volatile campos: Simplemente establece el indicador ACC_VOLATILE en el campo (JVM § 4.5 Fields). El código que tiene acceso al el campo usa el mismo bytecode, pero actúa ligeramente diferente.

También tenga en cuenta que el uso de solamente un campo volátil aquí es no threadsafe, porque x++ en un campo volátil x es no atómica!

4

La diferencia entre los dos primeros se encuentran justo aquí:

public int getNext(); 
    bytecodes follow... 

public synchronized int getNextSync(); 
    bytecodes follow... 

En cuanto a la última, volatile es una propiedad de la variable, no del método o los bytecodes JVM que tienen acceso a esa variable. Si nos fijamos en la parte superior de la salida javap, verá lo siguiente:

int last; 

volatile int lastVolatile; 

si/cuando los bytecodes se compilan en código de máquina por el compilador JIT, estoy seguro que el código de la máquina resultante será diferente para el último método

Cuestiones relacionadas