Различия jvm между синхронизированными и несинхронизированными методами - PullRequest
5 голосов
/ 05 октября 2011

У меня есть следующий класс:

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

}

Когда я смотрю на разобранный код, я не вижу различия между представлением трех методов getNext(), getNextSync() и 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

Как JMV может различать эти методы?

Сгенерированный код является тем же из этих методов, а также их вызывающих.Как JVM выполняет синхронизацию?

Ответы [ 2 ]

6 голосов
/ 05 октября 2011

Ключевое слово synchronized, применяемое к методу, просто устанавливает флаг ACC_SYNCHRONIZED в определении этого метода, как определено в спецификации JVM § 4.6 Методы .Он не будет виден в действительном байт-коде метода.

Синхронизированные методы JLS § 8.4.3.6 обсуждают сходство определения метода synchronized и объявления synchronizedблок, охватывающий все тело метода (и использующий тот же объект для синхронизации): эффект точно такой же, но они по-разному представлены в файле .class.

Aаналогичный эффект происходит с полями volatile: он просто устанавливает флаг ACC_VOLATILE в поле ( JVM § 4.5 Fields ).Код, к которому обращается * к полю, использует тот же байт-код, но действует немного иначе.

Также обратите внимание, что при использовании только изменяемое поле здесь не поточно, потому что x++ для изменчивого поля x равно не атомарному !

4 голосов
/ 05 октября 2011

Разница между первыми двумя прямо здесь:

public int getNext();
   bytecodes follow...

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

Что касается последнего, volatile является свойством переменной, а не метода или байтовых кодов JVM, которые обращаются к этой переменной,Если вы посмотрите на верхнюю часть вывода javap, вы увидите следующее:

int last;

volatile int lastVolatile;

Если / когда байтовые коды компилируются в машинный код компилятором JIT, я уверен, что полученная машинакод будет отличаться для последнего метода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...