【JVM学习笔记】图解Java Synchronized执行过程

- Synchronized用来给对象加锁,一段简单的示例代码:

public class SynchronizedDemo {

	//实例方法,同步方法,加锁对象是当前实例
	public synchronized void lockInstance() {
		System.out.println("Instance");
	}	

    public void lockThis() {
		synchronized(this) {  //明确指定this作为加锁对象
			System.out.println("'This'");
		}
	}	
	
  //另外,如果是static方法的话,加锁对象就是这个方法的class对象了,也就是为SynchronizedDemo生成的java.lang.Class的实例
}
  • 使用javap看lockInstance()字节码
        这个方法是实例方法,同时ACC_SYNCHRONIZED说明是同步方法,执行该方法使用monitorenter、monitorexit对实例对象进行加解锁
  public synchronized void lockInstance();
    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 Instance
         5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
      LineNumberTable:
        line 4: 0
        line 5: 8
  • 使用javap看lockThis()字节码
        更直观的,明确指定synchronized的作用对象
  public void lockThis();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=3, args_size=1
         0: aload_0
         1: dup
         2: astore_1
         3: monitorenter                      // 加锁
         4: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         7: ldc           #5                  // String 'This'
         9: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        12: aload_1
        13: monitorexit                      // 方法正常退出,解锁
        14: goto          22
        17: astore_2
        18: aload_1
        19: monitorexit                      // 方法异常退出,解锁
        20: aload_2
        21: athrow
        22: return
      Exception table:
         from    to  target type
             4    14    17   any
            17    20    17   any
      LineNumberTable:
        line 8: 0
        line 9: 4
        line 10: 12
        line 11: 22
      StackMapTable: number_of_entries = 2
        frame_type = 255 /* full_frame */
          offset_delta = 17
          locals = [ class SynchronizedDemo, class java/lang/Object ]
          stack = [ class java/lang/Throwable ]
        frame_type = 250 /* chop */
          offset_delta = 4

- 一个对象实例创建出来时,处于无锁状态
【JVM学习笔记】图解Java Synchronized执行过程_第1张图片
- synchorinzed在JVM层面是通过monitorenter和monitorexit来完成的

  • monitorenter的加锁过程【JVM学习笔记】图解Java Synchronized执行过程_第2张图片

  • 如果锁膨胀为重量级锁,获取过程如下
    【JVM学习笔记】图解Java Synchronized执行过程_第3张图片

- monitorexit解锁过程
【JVM学习笔记】图解Java Synchronized执行过程_第4张图片

    以上通过《深入理解Java虚拟机》和其它博客学习而来,本人理解上可能存在偏差,如有不当之处欢迎指正,不胜感激。

你可能感兴趣的:(Java,JVM)