synchronized 字节码解读

对象获取锁有三种途径:

1. 锁代码块
2. 锁方法
3. 锁静态方法

三种方式的字节码解读

1. 锁代码块
public class LockDemo {
    Object object = new Object();
    public void hello() {
        synchronized (object) {
        }
    }
}

在这里插入图片描述
代码块: 通过monitorentermonitorexit来实现判断是否枷锁
第二个monitorexit是防止我们中途中有其他的异常错误导致锁没有释放掉,所以这里才进行了第二次的释放锁

注意
一般来说 一个monitorenter 对两个 monitorexit,但是有时候也有特殊的情况,就是如果在代码中有异常的话那么就会只有一个monitorenter对应一个monitorexit,代码如下:

public class LockDemo {
    Object object = new Object();
    public void hello() {
        synchronized (object) {
            System.out.println("synchronized----");
            throw new RuntimeException("我要抛出异常了..");
        }
    }
}
  public void hello();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=3, 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     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
        10: ldc           #5                  // String synchronized----
        12: invokevirtual #6                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        15: new           #7                  // class java/lang/RuntimeException
        18: dup
        19: ldc           #8                  // String 我要抛出异常了..
        21: invokespecial #9                  // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
        24: athrow
        25: astore_2
        26: aload_1
        27: monitorexit//这里是释放, 注意这里只有这一次释放退出, 并没有两次释放
        28: aload_2
        29: athrow
      Exception table:
         from    to  target type
             7    28    25   any
      LineNumberTable:
        line 11: 0
        line 12: 7
        line 13: 15
        line 14: 25
      StackMapTable: number_of_entries = 1
        frame_type = 255 /* full_frame */
          offset_delta = 25
          locals = [ class com/lomonkey/synchronize/LockDemo, class java/lang/Object ]
          stack = [ class java/lang/Throwable ]
}
SourceFile: "LockDemo.java"

2. 锁方法
	public class LockDemo {
    public synchronized void hello() {
        System.out.println("--hello");
    }
}
public synchronized void hello();
    descriptor: ()V
    flags: ACC_PUBLIC, ACC_SYNCHRONIZED
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #3                  // String --hello
         5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
      LineNumberTable:
        line 10: 0
        line 11: 8

锁方法: 通过ACC_SYNCHRONIZED来获取是否给方法枷锁

3. 锁静态方法:
public class LockDemo {
    public static synchronized void hello() {
        System.out.println("--hello");
    }
}
  public static synchronized void hello();
    descriptor: ()V
    flags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED
    Code:
      stack=2, locals=0, args_size=0
         0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #3                  // String --hello
         5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
      LineNumberTable:
        line 10: 0
        line 11: 8
}
SourceFile: "LockDemo.java"

锁方法: 通过ACC_STATIC, ACC_SYNCHRONIZED来表示是否给静态方法枷锁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值