美文网首页
Concurrency: synchronized 字节码

Concurrency: synchronized 字节码

作者: CalmHeart | 来源:发表于2019-06-26 22:09 被阅读0次

synchronized 是并发中常用的关键字,用于方法或者是代码的同步,也是常见的面试点


使用javap -verbose -p Clazz 命令查看字节码

不带synchronized的方法

private void setX(int);
    descriptor: (I)V
    flags: (0x0002) ACC_PRIVATE
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: iload_1
         2: putfield      #2                  // Field x:I
         5: return
      LineNumberTable:
        line 9: 0
        line 10: 5
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       6     0  this   Lcom/compass/spring_lecture/binarycode/SynchronizedCode;
            0       6     1     x   I

加上synchronized的方法

private synchronized void setX(int);
    descriptor: (I)V
    flags: (0x0022) ACC_PRIVATE, ACC_SYNCHRONIZED
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: iload_1
         2: putfield      #2                  // Field x:I
         5: return
      LineNumberTable:
        line 9: 0
        line 10: 5
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       6     0  this   Lcom/compass/spring_lecture/binarycode/SynchronizedCode;
            0       6     1     x   I

修饰的是方法,并不是代码块并不会体现monitorenter及monitorexit

可重入锁,一个线程获取锁之后可以继续获取,获取N次必须释放N次 自带计数器 标记进入和出来的次数。


其他线程阻塞、或者使用自旋锁(占用cpu资源)。
是一个重量级的锁,新版本的jdk对synchronized已经做了优化,建议使用Lock或ReentrantLock
source code:

private void test(){

    synchronized (object){

      System.out.println("welcome");

    }

  }

反编译:


private void test();
    descriptor: ()V
    flags: (0x0002) ACC_PRIVATE
    Code:
      stack=2, locals=3, args_size=1
         0: aload_0
         1: getfield      #3                  // Field object:Ljava/lang/Object;
         4: dup
         5: astore_1
         ----------------------------------
         6: monitorenter
         7: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
        10: ldc           #6                    // String welcome
        12: invokevirtual #7               // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        15: aload_1
        16: monitorexit                      //正常的退出
        ----------------------------------
        17: goto          25
        20: astore_2
        21: aload_1
        22: monitorexit                       //异常的退出
        23: aload_2
        24: athrow
        25: return
      Exception table:
         from    to  target type
             7    17    20   any
            20    23    20   any
      LineNumberTable:
        line 17: 0
        line 19: 7
        line 21: 15
        line 23: 25
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      26     0  this   Lcom/compass/spring_lecture/binarycode/SynchronizedCode;
      StackMapTable: number_of_entries = 2
        frame_type = 255 /* full_frame */
          offset_delta = 20
          locals = [ class com/compass/spring_lecture/binarycode/SynchronizedCode, class java/lang/Object ]
          stack = [ class java/lang/Throwable ]
        frame_type = 250 /* chop */
          offset_delta = 4

静态synchronized方法:

private synchronized static void test2() {

  }

 private static synchronized void test2();
    descriptor: ()V
    flags: (0x002a) ACC_PRIVATE, ACC_STATIC, ACC_SYNCHRONIZED
    Code:
      stack=0, locals=0, args_size=0
         0: return
      LineNumberTable:
        line 28: 0

相关文章

网友评论

      本文标题:Concurrency: synchronized 字节码

      本文链接:https://www.haomeiwen.com/subject/ahghcctx.html