一、源代码:
package cn.edu.tju.controller;
public class TestSync {
private Object object=new Object();
public static void main(String[] args) {
System.out.println("hello,world");
}
public synchronized void test1(){
System.out.println("in test1......");
}
public void test2(){
synchronized (object){
}
System.out.println("in test2......");
}
}
二、生成字节码:
javap -verbose TestSync
Last modified 2022-6-18; size 943 bytes
MD5 checksum 06b516d40f8d065dc2357d3bd8428bd3
Compiled from "TestSync.java"
public class cn.edu.tju.controller.TestSync
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #2.#31 // java/lang/Object."<init>":()V
#2 = Class #32 // java/lang/Object
#3 = Fieldref #9.#33 // cn/edu/tju/controller/TestSync.object:Ljava/lang/Object;
#4 = Fieldref #34.#35 // java/lang/System.out:Ljava/io/PrintStream;
#5 = String #36 // hello,world
#6 = Methodref #37.#38 // java/io/PrintStream.println:(Ljava/lang/String;)V
#7 = String #39 // in test1......
#8 = String #40 // in test2......
#9 = Class #41 // cn/edu/tju/controller/TestSync
#10 = Utf8 object
#11 = Utf8 Ljava/lang/Object;
#12 = Utf8 <init>
#13 = Utf8 ()V
#14 = Utf8 Code
#15 = Utf8 LineNumberTable
#16 = Utf8 LocalVariableTable
#17 = Utf8 this
#18 = Utf8 Lcn/edu/tju/controller/TestSync;
#19 = Utf8 main
#20 = Utf8 ([Ljava/lang/String;)V
#21 = Utf8 args
#22 = Utf8 [Ljava/lang/String;
#23 = Utf8 test1
#24 = Utf8 test2
#25 = Utf8 StackMapTable
#26 = Class #41 // cn/edu/tju/controller/TestSync
#27 = Class #32 // java/lang/Object
#28 = Class #42 // java/lang/Throwable
#29 = Utf8 SourceFile
#30 = Utf8 TestSync.java
#31 = NameAndType #12:#13 // "<init>":()V
#32 = Utf8 java/lang/Object
#33 = NameAndType #10:#11 // object:Ljava/lang/Object;
#34 = Class #43 // java/lang/System
#35 = NameAndType #44:#45 // out:Ljava/io/PrintStream;
#36 = Utf8 hello,world
#37 = Class #46 // java/io/PrintStream
#38 = NameAndType #47:#48 // println:(Ljava/lang/String;)V
#39 = Utf8 in test1......
#40 = Utf8 in test2......
#41 = Utf8 cn/edu/tju/controller/TestSync
#42 = Utf8 java/lang/Throwable
#43 = Utf8 java/lang/System
#44 = Utf8 out
#45 = Utf8 Ljava/io/PrintStream;
#46 = Utf8 java/io/PrintStream
#47 = Utf8 println
#48 = Utf8 (Ljava/lang/String;)V
{
public cn.edu.tju.controller.TestSync();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=3, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: new #2 // class java/lang/Object
8: dup
9: invokespecial #1 // Method java/lang/Object."<init>":()V
12: putfield #3 // Field object:Ljava/lang/Object;
15: return
LineNumberTable:
line 3: 0
line 4: 4
LocalVariableTable:
Start Length Slot Name Signature
0 16 0 this Lcn/edu/tju/controller/TestSync;
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #5 // String hello,world
5: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 6: 0
line 7: 8
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 args [Ljava/lang/String;
public synchronized void test1();
descriptor: ()V
flags: ACC_PUBLIC, ACC_SYNCHRONIZED
Code:
stack=2, locals=1, args_size=1
0: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #7 // String in test1......
5: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 10: 0
line 11: 8
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 this Lcn/edu/tju/controller/TestSync;
public void test2();
descriptor: ()V
flags: ACC_PUBLIC
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: aload_1
8: monitorexit
9: goto 17
12: astore_2
13: aload_1
14: monitorexit
15: aload_2
16: athrow
17: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
20: ldc #8 // String in test2......
22: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
25: return
Exception table:
from to target type
7 9 12 any
12 15 12 any
LineNumberTable:
line 14: 0
line 16: 7
line 17: 17
line 18: 25
LocalVariableTable:
Start Length Slot Name Signature
0 26 0 this Lcn/edu/tju/controller/TestSync;
StackMapTable: number_of_entries = 2
frame_type = 255 /* full_frame */
offset_delta = 12
locals = [ class cn/edu/tju/controller/TestSync, class java/lang/Object ]
stack = [ class java/lang/Throwable ]
frame_type = 250 /* chop */
offset_delta = 4
}
SourceFile: "TestSync.java"
三、结论:
只有synchronized关键字修饰代码块的时候才会显式出现monitorenter和monitorexit指令,而修饰方法时,只会改变方法表中该方法的access_flag