• 第13章 线程安全与锁优化+字节码解析


    1、概述

    2、synchronized原理

     3、字节码分析

     Class组成:

    引用参考:https://snailclimb.gitee.io/javaguide/#/docs/java/jvm/%E7%B1%BB%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84

    举例1:

    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: 52 //主版本号
      flags: ACC_PUBLIC, ACC_SUPER //访问标志,ACC_PUBLIC是否为public类型, ACC_SUPER是否允许使用invokespecial字节码指令
    Constant pool://常量池
       #1 = Class              #2             // com/javabasic/synchronizeds/ShareData (#2是一个索引值,指向常量池中Utf8类型常量,代表类或接口的全限定名)#
       #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 (java.lang.Object类的<init>方法)
      #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 //Code属性,JDK1.5中新增的属性,共新类型检查验证器(Type Checker)检查和处理目标方法的局部变量和操作数栈锁需要的类型是否匹配
      #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: //方法表,Java代码遍历成的字节码指令
          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: //Code属性,Java源码的行号与字节码指令的对应关系
            line 8: 0
            line 9: 10
          LocalVariableTable: //Code属性,方法的局部变量描述
            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"
  • 相关阅读:
    STL set
    STL pair
    STL简介
    最长公共子序列lcs
    MySQL常用内置函数整理
    MySQL注入点写webshell的五种方式
    phpAdmin写webshell的方法
    mysql之突破secure_file_priv写webshell
    MySQL提权之启动项提权
    MySQL提权之mof提权
  • 原文地址:https://www.cnblogs.com/wangymd/p/12966281.html
Copyright © 2020-2023  润新知