Synchronized的使用方式
Synchronized
作用于普通方法、静态方法、同步代码块。通过javap -v
命令深入查看。
代码示例:
public class SyncUsingWay {
public synchronized void syncMethod() { System.out.println("Synchronized Method"); }
public synchronized static void staticSyncMethod() { System.out.println("Static Synchronized Method"); }
public void method() { synchronized (this) { System.out.println("Method"); } } }
|
编译之后,使用javap -v SyncUsingWay.class
查看信息:
Classfile /Users/codejuzi/Documents/CodeWorkSpace/Practice/juc-demo/target/classes/com/juzi/juc/sync/SyncUsingWay.class Last modified 2023-12-1; size 839 bytes MD5 checksum 594bba00a6d14034bd77c93025a9dd13 Compiled from "SyncUsingWay.java" public class com.juzi.juc.sync.SyncUsingWay minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #8.#25 #2 = Fieldref #26.#27 #3 = String #28 #4 = Methodref #29.#30 #5 = String #31 #6 = String #32 #7 = Class #33 #8 = Class #34 #9 = Utf8 <init> #10 = Utf8 ()V #11 = Utf8 Code #12 = Utf8 LineNumberTable #13 = Utf8 LocalVariableTable #14 = Utf8 this #15 = Utf8 Lcom/juzi/juc/sync/SyncUsingWay; #16 = Utf8 syncMethod #17 = Utf8 staticSyncMethod #18 = Utf8 method #19 = Utf8 StackMapTable #20 = Class #33 #21 = Class #34 #22 = Class #35 #23 = Utf8 SourceFile #24 = Utf8 SyncUsingWay.java #25 = NameAndType #9:#10 #26 = Class #36 #27 = NameAndType #37:#38 #28 = Utf8 Synchronized Method #29 = Class #39 #30 = NameAndType #40:#41 #31 = Utf8 Static Synchronized Method #32 = Utf8 Method #33 = Utf8 com/juzi/juc/sync/SyncUsingWay #34 = Utf8 java/lang/Object #35 = Utf8 java/lang/Throwable #36 = Utf8 java/lang/System #37 = Utf8 out #38 = Utf8 Ljava/io/PrintStream; #39 = Utf8 java/io/PrintStream #40 = Utf8 println #41 = Utf8 (Ljava/lang/String;)V { public com.juzi.juc.sync.SyncUsingWay(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 4: return LineNumberTable: line 6: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Lcom/juzi/juc/sync/SyncUsingWay;
public synchronized void syncMethod(); descriptor: ()V flags: ACC_PUBLIC, ACC_SYNCHRONIZED Code: stack=2, locals=1, args_size=1 0: getstatic #2 3: ldc #3 5: invokevirtual #4 8: return LineNumberTable: line 13: 0 line 14: 8 LocalVariableTable: Start Length Slot Name Signature 0 9 0 this Lcom/juzi/juc/sync/SyncUsingWay;
public static synchronized void staticSyncMethod(); descriptor: ()V flags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED Code: stack=2, locals=0, args_size=0 0: getstatic #2 3: ldc #5 5: invokevirtual #4 8: return LineNumberTable: line 22: 0 line 23: 8
public void method(); 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 7: ldc #6 9: invokevirtual #4 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 27: 0 line 28: 4 line 29: 12 line 30: 22 LocalVariableTable: Start Length Slot Name Signature 0 23 0 this Lcom/juzi/juc/sync/SyncUsingWay; StackMapTable: number_of_entries = 2 frame_type = 255 offset_delta = 17 locals = [ class com/juzi/juc/sync/SyncUsingWay, class java/lang/Object ] stack = [ class java/lang/Throwable ] frame_type = 250 offset_delta = 4 } SourceFile: "SyncUsingWay.java"
|
SyncMethod
普通同步方法
public synchronized void syncMethod(); descriptor: ()V flags: ACC_PUBLIC, ACC_SYNCHRONIZED Code: stack=2, locals=1, args_size=1 0: getstatic #2 3: ldc #3 5: invokevirtual #4 8: return LineNumberTable: line 13: 0 line 14: 8 LocalVariableTable: Start Length Slot Name Signature 0 9 0 this Lcom/juzi/juc/sync/SyncUsingWay;
|
flag中ACC_SYNCHRONIZED是加锁的标志,编译期生成。
StaticSyncMethod
静态同步方法中flag部分相比于普通同步方法增加了ACC_STATIC。
method
同步代码块的字节码信息的flag信息中并没有任何与synchronized有关的标志。但是在Code区域中,存在monitorenter
和monitorexit
。
3: monitorenter ... 13: monitorexit ... 19: monitorexit ... Exception table: ...
|
monitorenter
:标志进入同步代码块(临界范围内,锁的原子内部)
- 第一个
monitorexit
:正常退出同步代码块
- 第二个
monitorexit
:异常情况下的退出同步代码块。在异常情况下,JVM依然可以正常退出锁。
Exception table
:在异常情况下配合JVM退出锁
资料:https://www.bilibili.com/video/BV1dv411c79B/ 强推 河北王校长