2011-10-05 3 views
5

je la classe suivante:différences jvm entre les méthodes synchronisées et non synchronisées

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(); 
    } 

} 

Quand je regarde le code désassemblé je ne vois pas la différence entre la représentation des trois méthodes getNext(), getNextSync() et 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 

Comment le JMV peut-il distinguer ces méthodes?

Le code généré est le même de ces méthodes et également de leurs appelants. Comment la JVM effectue la synchronisation?

Répondre

6

Le mot-clé synchronized appliqué à une méthode définit simplement l'indicateur ACC_SYNCHRONIZED sur cette définition de méthode, comme défini dans the JVM specification § 4.6 Methods. Il ne sera pas visible dans le bytecode réel de la méthode.

Le JLS § 8.4.3.6 synchronized Methods traite de la similitude de la définition d'une méthode synchronized et déclarer un bloc synchronized qui couvre tout le corps de la méthode (et en utilisant le même objet pour synchroniser le): le effet est exactement la même, mais ils sont représentés différemment dans le fichier .class.

Un effet similaire se produit avec volatile champs: Il définit simplement le drapeau ACC_VOLATILE sur le terrain (JVM § 4.5 Fields). Le code accède à le champ utilise le même bytecode, mais agit légèrement différent.

s'il vous plaît noter également que l'utilisation ne un champ volatile est ici pas threadsafe, parce x++ sur un champ volatile x est pas atomique!

4

La différence entre les deux premiers est ici:

public int getNext(); 
    bytecodes follow... 

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

Quant au dernier, volatile est une propriété de la variable, et non de la méthode ou le bytecode JVM qui ont accès à cette variable. Si vous regardez en haut de la sortie javap, vous verrez les éléments suivants:

int last; 

volatile int lastVolatile; 

Si/quand le bytecode sont compilés en code machine par le compilateur JIT, je suis sûr que le code de la machine obtenue différera pour la dernière méthode.

Questions connexes