Synchronized 수식 방법 과 코드 블록 이 밑 에 있 는 차이 점
16617 단어 자바 진격 의 길
수식 코드 블록
인 스 턴 스 를 수식 하 는 방법수식 정태 방법
총화
수식 코드 블록
위의 예:
public class SyncCodeBlock {
public int i;
public void syncTask(){
//
synchronized (this){
i++;
}
}
}
자바 c 컴 파일 을 사용 하여 자바 p 로 바이트 코드 를 봅 니 다:
$javac SyncCodeBlock.java
$javap -v -c -s -l SyncCodeBlock.class
Classfile /Users/mac/IdeaProjects/multiThread/src/main/java/ThreadBasic/Synchronized/SyncCodeBlock.class
Last modified 2020-6-26; size 427 bytes
MD5 checksum 46c58b50c71e6579e6e3d8b903ac2680
Compiled from "SyncCodeBlock.java"
public class ThreadBasic.Synchronized.SyncCodeBlock
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #4.#18 // java/lang/Object."":()V
#2 = Fieldref #3.#19 // ThreadBasic/Synchronized/SyncCodeBlock.i:I
#3 = Class #20 // ThreadBasic/Synchronized/SyncCodeBlock
#4 = Class #21 // java/lang/Object
#5 = Utf8 i
#6 = Utf8 I
#7 = Utf8
#8 = Utf8 ()V
#9 = Utf8 Code
#10 = Utf8 LineNumberTable
#11 = Utf8 syncTask
#12 = Utf8 StackMapTable
#13 = Class #20 // ThreadBasic/Synchronized/SyncCodeBlock
#14 = Class #21 // java/lang/Object
#15 = Class #22 // java/lang/Throwable
#16 = Utf8 SourceFile
#17 = Utf8 SyncCodeBlock.java
#18 = NameAndType #7:#8 // "":()V
#19 = NameAndType #5:#6 // i:I
#20 = Utf8 ThreadBasic/Synchronized/SyncCodeBlock
#21 = Utf8 java/lang/Object
#22 = Utf8 java/lang/Throwable
{
public int i;
descriptor: I
flags: ACC_PUBLIC
public ThreadBasic.Synchronized.SyncCodeBlock();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."":()V
4: return
LineNumberTable:
line 3: 0
public void syncTask();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=3, locals=3, args_size=1
0: aload_0
1: dup
2: astore_1
3: monitorenter
4: aload_0
5: dup
6: getfield #2 // Field i:I
9: iconst_1
10: iadd
11: putfield #2 // Field i:I
14: aload_1
15: monitorexit
16: goto 24
19: astore_2
20: aload_1
21: monitorexit
22: aload_2
23: athrow
24: return
Exception table:
from to target type
4 16 19 any
19 22 19 any
LineNumberTable:
line 9: 0
line 10: 4
line 11: 14
line 12: 24
StackMapTable: number_of_entries = 2
frame_type = 255 /* full_frame */
offset_delta = 19
locals = [ class ThreadBasic/Synchronized/SyncCodeBlock, class java/lang/Object ]
stack = [ class java/lang/Throwable ]
frame_type = 250 /* chop */
offset_delta = 4
}
SourceFile: "SyncCodeBlock.java"
JVM 은 입력,종료 대상 모니터(Monitor)를 통 해 코드 블록 에 대한 동기 화 를 실현 합 니 다.
수식 실례 방법
public class SyncInstance implements Runnable{
static int i = 0;
public synchronized void increase() {
i++;
}
@Override
public void run() {
for (int j = 0; j < 5; j++) {
increase();
}
}
public static void main(String[] args) throws InterruptedException {
//new
Thread t1 = new Thread(new SyncInstance());
//new
t1.start();
//join : A thread thread.join()
t1.join();
}
}
바이트 코드 보기:
$javac SyncInstance.java
$javap -v -c -s -l SyncInstance.class
Classfile /Users/mac/IdeaProjects/multiThread/src/main/java/ThreadBasic/Synchronized/SyncInstance.class
Last modified 2020-6-26; size 769 bytes
MD5 checksum 4bc0bc765b64da5799760cf7a04b01cc
Compiled from "SyncInstance.java"
public class ThreadBasic.Synchronized.SyncInstance implements java.lang.Runnable
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #10.#28 // java/lang/Object."":()V
#2 = Fieldref #5.#29 // ThreadBasic/Synchronized/SyncInstance.i:I
#3 = Methodref #5.#30 // ThreadBasic/Synchronized/SyncInstance.increase:()V
#4 = Class #31 // java/lang/Thread
#5 = Class #32 // ThreadBasic/Synchronized/SyncInstance
#6 = Methodref #5.#28 // ThreadBasic/Synchronized/SyncInstance."":()V
#7 = Methodref #4.#33 // java/lang/Thread."":(Ljava/lang/Runnable;)V
#8 = Methodref #4.#34 // java/lang/Thread.start:()V
#9 = Methodref #4.#35 // java/lang/Thread.join:()V
#10 = Class #36 // java/lang/Object
#11 = Class #37 // java/lang/Runnable
#12 = Utf8 i
#13 = Utf8 I
#14 = Utf8
#15 = Utf8 ()V
#16 = Utf8 Code
#17 = Utf8 LineNumberTable
#18 = Utf8 increase
#19 = Utf8 run
#20 = Utf8 StackMapTable
#21 = Utf8 main
#22 = Utf8 ([Ljava/lang/String;)V
#23 = Utf8 Exceptions
#24 = Class #38 // java/lang/InterruptedException
#25 = Utf8
#26 = Utf8 SourceFile
#27 = Utf8 SyncInstance.java
#28 = NameAndType #14:#15 // "":()V
#29 = NameAndType #12:#13 // i:I
#30 = NameAndType #18:#15 // increase:()V
#31 = Utf8 java/lang/Thread
#32 = Utf8 ThreadBasic/Synchronized/SyncInstance
#33 = NameAndType #14:#39 // "":(Ljava/lang/Runnable;)V
#34 = NameAndType #40:#15 // start:()V
#35 = NameAndType #41:#15 // join:()V
#36 = Utf8 java/lang/Object
#37 = Utf8 java/lang/Runnable
#38 = Utf8 java/lang/InterruptedException
#39 = Utf8 (Ljava/lang/Runnable;)V
#40 = Utf8 start
#41 = Utf8 join
{
static int i;
descriptor: I
flags: ACC_STATIC
public ThreadBasic.Synchronized.SyncInstance();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."":()V
4: return
LineNumberTable:
line 3: 0
public synchronized void increase();
descriptor: ()V
flags: ACC_PUBLIC, ACC_SYNCHRONIZED
Code:
stack=2, locals=1, args_size=1
0: getstatic #2 // Field i:I
3: iconst_1
4: iadd
5: putstatic #2 // Field i:I
8: return
LineNumberTable:
line 7: 0
line 8: 8
public void run();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=2, args_size=1
0: iconst_0
1: istore_1
2: iload_1
3: iconst_5
4: if_icmpge 17
7: aload_0
8: invokevirtual #3 // Method increase:()V
11: iinc 1, 1
14: goto 2
17: return
LineNumberTable:
line 12: 0
line 13: 7
line 12: 11
line 15: 17
StackMapTable: number_of_entries = 2
frame_type = 252 /* append */
offset_delta = 2
locals = [ int ]
frame_type = 250 /* chop */
offset_delta = 14
public static void main(java.lang.String[]) throws java.lang.InterruptedException;
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=4, locals=2, args_size=1
0: new #4 // class java/lang/Thread
3: dup
4: new #5 // class ThreadBasic/Synchronized/SyncInstance
7: dup
8: invokespecial #6 // Method "":()V
11: invokespecial #7 // Method java/lang/Thread."":(Ljava/lang/Runnable;)V
14: astore_1
15: aload_1
16: invokevirtual #8 // Method java/lang/Thread.start:()V
19: aload_1
20: invokevirtual #9 // Method java/lang/Thread.join:()V
23: return
LineNumberTable:
line 19: 0
line 21: 15
line 23: 19
line 24: 23
Exceptions:
throws java.lang.InterruptedException
static {};
descriptor: ()V
flags: ACC_STATIC
Code:
stack=1, locals=0, args_size=0
0: iconst_0
1: putstatic #2 // Field i:I
4: return
LineNumberTable:
line 4: 0
}
SourceFile: "SyncInstance.java"
synchronized 수식 의 인 스 턴 스 방법 은 Monitorenter 명령 과 Monitorexit 명령 이 없 으 며 대신 ACCSYNCHRONIZED 표 지 는 이 방법 이 동기 화 방법 임 을 가리 키 며 JVM 은 이 ACC 를 통 해SYNCHRONIZED 방문 표 지 는 하나의 방법 이 동기 화 방법 인지 여 부 를 판별 하여 해당 하 는 동기 화 호출 을 수행 합 니 다.
수식 정적 방법
package ThreadBasic.Synchronized;
public class SynStatic implements Runnable {
static int i = 0;
public static synchronized void increase() {
i++;
}
@Override
public void run() {
for (int j = 0; j < 5; j++) {
increase();
}
}
public static void main(String[] args) throws InterruptedException {
//new
Thread t1 = new Thread(new SynStatic());
//new
t1.start();
//join : A thread thread.join()
t1.join();
}
}
바이트 코드 보기:
$javac SynStatic.java
$javap -c -v -s -l SynStatic.class
Classfile /Users/mac/IdeaProjects/multiThread/src/main/java/ThreadBasic/Synchronized/SynStatic.class
Last modified 2020-6-26; size 762 bytes
MD5 checksum f66c06958c4b1a7b9e84d47933cc6dda
Compiled from "SynStatic.java"
public class ThreadBasic.Synchronized.SynStatic implements java.lang.Runnable
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #10.#28 // java/lang/Object."":()V
#2 = Fieldref #5.#29 // ThreadBasic/Synchronized/SynStatic.i:I
#3 = Methodref #5.#30 // ThreadBasic/Synchronized/SynStatic.increase:()V
#4 = Class #31 // java/lang/Thread
#5 = Class #32 // ThreadBasic/Synchronized/SynStatic
#6 = Methodref #5.#28 // ThreadBasic/Synchronized/SynStatic."":()V
#7 = Methodref #4.#33 // java/lang/Thread."":(Ljava/lang/Runnable;)V
#8 = Methodref #4.#34 // java/lang/Thread.start:()V
#9 = Methodref #4.#35 // java/lang/Thread.join:()V
#10 = Class #36 // java/lang/Object
#11 = Class #37 // java/lang/Runnable
#12 = Utf8 i
#13 = Utf8 I
#14 = Utf8
#15 = Utf8 ()V
#16 = Utf8 Code
#17 = Utf8 LineNumberTable
#18 = Utf8 increase
#19 = Utf8 run
#20 = Utf8 StackMapTable
#21 = Utf8 main
#22 = Utf8 ([Ljava/lang/String;)V
#23 = Utf8 Exceptions
#24 = Class #38 // java/lang/InterruptedException
#25 = Utf8
#26 = Utf8 SourceFile
#27 = Utf8 SynStatic.java
#28 = NameAndType #14:#15 // "":()V
#29 = NameAndType #12:#13 // i:I
#30 = NameAndType #18:#15 // increase:()V
#31 = Utf8 java/lang/Thread
#32 = Utf8 ThreadBasic/Synchronized/SynStatic
#33 = NameAndType #14:#39 // "":(Ljava/lang/Runnable;)V
#34 = NameAndType #40:#15 // start:()V
#35 = NameAndType #41:#15 // join:()V
#36 = Utf8 java/lang/Object
#37 = Utf8 java/lang/Runnable
#38 = Utf8 java/lang/InterruptedException
#39 = Utf8 (Ljava/lang/Runnable;)V
#40 = Utf8 start
#41 = Utf8 join
{
static int i;
descriptor: I
flags: ACC_STATIC
public ThreadBasic.Synchronized.SynStatic();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."":()V
4: return
LineNumberTable:
line 3: 0
public static synchronized void increase();
descriptor: ()V
flags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED
Code:
stack=2, locals=0, args_size=0
0: getstatic #2 // Field i:I
3: iconst_1
4: iadd
5: putstatic #2 // Field i:I
8: return
LineNumberTable:
line 7: 0
line 8: 8
public void run();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=2, args_size=1
0: iconst_0
1: istore_1
2: iload_1
3: iconst_5
4: if_icmpge 16
7: invokestatic #3 // Method increase:()V
10: iinc 1, 1
13: goto 2
16: return
LineNumberTable:
line 12: 0
line 13: 7
line 12: 10
line 15: 16
StackMapTable: number_of_entries = 2
frame_type = 252 /* append */
offset_delta = 2
locals = [ int ]
frame_type = 250 /* chop */
offset_delta = 13
public static void main(java.lang.String[]) throws java.lang.InterruptedException;
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=4, locals=2, args_size=1
0: new #4 // class java/lang/Thread
3: dup
4: new #5 // class ThreadBasic/Synchronized/SynStatic
7: dup
8: invokespecial #6 // Method "":()V
11: invokespecial #7 // Method java/lang/Thread."":(Ljava/lang/Runnable;)V
14: astore_1
15: aload_1
16: invokevirtual #8 // Method java/lang/Thread.start:()V
19: aload_1
20: invokevirtual #9 // Method java/lang/Thread.join:()V
23: return
LineNumberTable:
line 19: 0
line 21: 15
line 23: 19
line 24: 23
Exceptions:
throws java.lang.InterruptedException
static {};
descriptor: ()V
flags: ACC_STATIC
Code:
stack=1, locals=0, args_size=0
0: iconst_0
1: putstatic #2 // Field i:I
4: return
LineNumberTable:
line 4: 0
}
SourceFile: "SynStatic.java"
synchronized 수식 의 정적 방법 도 Monitorenter 명령 과 Monitorexit 명령 이 없 으 며 대신 ACC 를 얻 었 습 니 다.SYNCHRONIZED 표지;
총결산
synchronized 가 코드 블록 을 수식 할 때:동기 구문 블록 의 실현 은 Monitorenter 와 Monitorexit 명령 을 사용 합 니 다.그 중에서 Monitorenter 명령 은 동기 코드 블록 의 시작 위 치 를 가리 키 고 Monitorexit 명령 은 동기 코드 블록 의 끝 위 치 를 가리 킵 니 다.synchronized 수식 방법:synchronized 수식 방법 은 Monitorenter 명령 과 Monitorexit 명령 이 없 으 며 대신 ACCSYNCHRONIZED 표 지 는 이 방법 이 동기 화 방법 임 을 가리 키 며 JVM 은 이 ACC 를 통 해SYNCHRONIZED 접근 표 지 는 하나의 방법 이 동기 화 방법 인지 여 부 를 판별 하여 해당 하 는 동기 화 호출 을 수행 합 니 다.