jvm同步和非同步方法之间的差异

Ole*_*liv 5 java jvm

我有以下课程:

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

}
Run Code Online (Sandbox Code Playgroud)

当我看到反汇编的代码时,我没有看到三种方法的表示之间的区别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
Run Code Online (Sandbox Code Playgroud)

JMV如何区分这些方法?

生成的代码与这些方法以及它们的调用者相同.JVM如何执行同步?

Joa*_*uer 6

synchronized应用于方法的关键字仅ACC_SYNCHRONIZED在该方法定义上设置标志,如JVM规范§4.6方法中所定义.它在方法的实际字节码中不可见.

所述JLS§8.4.3.6同步方法讨论限定的相似 synchronized方法和声明一个synchronized跨越整个方法体块(并使用相同的对象上同步):在效果是完全一样的,但是它们在表示不同.class文件.

volatile字段也会产生类似的效果:它只是ACC_VOLATILE字段上设置标志(JVM§4.5字段).访问该字段的代码使用相同的字节码,但行为略有不同.

另请注意,此处使用volatile字段不是线程安全的,因为x++在volatile字段x不是原子的!