synchronized底层原理
Posted wangymd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了synchronized底层原理相关的知识,希望对你有一定的参考价值。
1、整理的思维导图
2、字节码分析
package com.javabasic.synchronizeds; public class ShareData { int num; public synchronized void increase1() { num++; } public void increase2() { synchronized(this) { num++; } } public void increase3() { synchronized(ShareData.class) { num++; } } public int getNum() { return num; } }
javap -c -l -s -v ShareData.class 命令查看字节码:
Classfile /E:/workspace170208/JavaBasicTest/target/classes/com/javabasic/synchronizeds/ShareData.class Last modified 2020-5-26; size 850 bytes MD5 checksum 666a7a0b1a6ab9b525f32276cb6cd699 Compiled from "ShareData.java" public class com.javabasic.synchronizeds.ShareData minor version: 0 //最小版本 major version: 50 //最大版本 flags: ACC_PUBLIC, ACC_SUPER //访问标志,ACC_PUBLIC是否为public类型, ACC_SUPER是否允许使用invokespecial字节码指令 Constant pool://常量池 #1 = Class #2 // com/javabasic/synchronizeds/ShareData #2 = Utf8 com/javabasic/synchronizeds/ShareData #3 = Class #4 // java/lang/Object #4 = Utf8 java/lang/Object #5 = Utf8 num #6 = Utf8 I #7 = Utf8 <init> #8 = Utf8 ()V #9 = Utf8 Code #10 = Methodref #3.#11 // java/lang/Object."<init>":()V #11 = NameAndType #7:#8 // "<init>":()V #12 = Utf8 LineNumberTable #13 = Utf8 LocalVariableTable #14 = Utf8 this #15 = Utf8 Lcom/javabasic/synchronizeds/ShareData; #16 = Utf8 increase1 #17 = Fieldref #1.#18 // com/javabasic/synchronizeds/ShareData.num:I #18 = NameAndType #5:#6 // num:I #19 = Utf8 increase2 #20 = Utf8 StackMapTable #21 = Class #22 // java/lang/Throwable #22 = Utf8 java/lang/Throwable #23 = Utf8 increase3 #24 = Class #25 // java/lang/Class #25 = Utf8 java/lang/Class #26 = Utf8 getNum #27 = Utf8 ()I #28 = Utf8 SourceFile #29 = Utf8 ShareData.java { int num; descriptor: I flags: public com.javabasic.synchronizeds.ShareData();//默认构造方法 descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #10 // Method java/lang/Object."<init>":()V //调用超类构造方法,实例初始化方法,私有方法 4: return LineNumberTable: line 3: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Lcom/javabasic/synchronizeds/ShareData; public synchronized void increase1(); descriptor: ()V flags: ACC_PUBLIC, ACC_SYNCHRONIZED //同步方法标识 Code: stack=3, locals=1, args_size=1 0: aload_0 //将第一个引用类型本地变量推送至栈顶 1: dup ///复制栈顶数值并将复制值压入栈顶 2: getfield #17 // Field num:I //获取指定类的实例域,并将其值压入栈顶 5: iconst_1 //将int型1推送至栈顶 6: iadd //将栈顶两个int型数值相加将结果压入栈顶 7: putfield #17 // Field num:I //为指定的类的实例域赋值 10: return //从当前方法返回void LineNumberTable: line 8: 0 line 9: 10 LocalVariableTable: Start Length Slot Name Signature 0 11 0 this Lcom/javabasic/synchronizeds/ShareData; public void increase2(); descriptor: ()V flags: ACC_PUBLIC Code: stack=3, locals=2, args_size=1 0: aload_0 //将第一个引用类型本地变量推送至栈顶 1: dup //复制栈顶数值并将复制值压入栈顶 2: astore_1 //将栈顶引用型数值存入第二个本地变量 3: monitorenter //获得对象的锁,用于同步方法或同步块 4: aload_0 //将第二个引用类型本地变量推送至栈顶 5: dup //复制栈顶数值并将复制值压入栈顶 6: getfield #17 // Field num:I //获取指定类的实例域,并将其值压入栈顶 9: iconst_1 //将int型1推送至栈顶 10: iadd //将栈顶两个int型数值相加将结果压入栈顶 11: putfield #17 // Field num:I //为指定的类的实例域赋值 14: aload_1 //将第二个引用类型本地变量推送至栈顶 15: monitorexit //释放对象的锁,用于同步方法或同步块 16: goto 22 //无条件跳转 19: aload_1 //将第二个引用类型本地变量推送至栈顶 20: monitorexit //释放对象的锁,用于同步方法或同步块 21: athrow //将栈顶的异常抛出 22: return Exception table: from to target type 4 16 19 any 19 21 19 any LineNumberTable: line 12: 0 line 13: 4 line 12: 14 line 15: 22 LocalVariableTable: Start Length Slot Name Signature 0 23 0 this Lcom/javabasic/synchronizeds/ShareData; StackMapTable: number_of_entries = 2 frame_type = 255 /* full_frame */ offset_delta = 19 locals = [ class com/javabasic/synchronizeds/ShareData, class com/javabasic/synchronizeds/ShareData ] stack = [ class java/lang/Throwable ] frame_type = 250 /* chop */ offset_delta = 2 public void increase3(); descriptor: ()V flags: ACC_PUBLIC Code: stack=3, locals=2, args_size=1 0: ldc #1 // class com/javabasic/synchronizeds/ShareData 2: dup 3: astore_1 4: monitorenter 5: aload_0 6: dup 7: getfield #17 // Field num:I 10: iconst_1 11: iadd 12: putfield #17 // Field num:I 15: aload_1 16: monitorexit 17: goto 23 20: aload_1 21: monitorexit 22: athrow 23: return Exception table: from to target type 5 17 20 any 20 22 20 any LineNumberTable: line 18: 0 line 19: 5 line 18: 15 line 21: 23 LocalVariableTable: Start Length Slot Name Signature 0 24 0 this Lcom/javabasic/synchronizeds/ShareData; StackMapTable: number_of_entries = 2 frame_type = 255 /* full_frame */ offset_delta = 20 locals = [ class com/javabasic/synchronizeds/ShareData, class java/lang/Class ] stack = [ class java/lang/Throwable ] frame_type = 250 /* chop */ offset_delta = 2 public int getNum(); descriptor: ()I flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: getfield #17 // Field num:I 4: ireturn LineNumberTable: line 24: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Lcom/javabasic/synchronizeds/ShareData; } SourceFile: "ShareData.java"
以上是关于synchronized底层原理的主要内容,如果未能解决你的问题,请参考以下文章
JVMday03类文件结构 字节码指令 多态的原理 异常 synchronized代码块底层原理