synchronized 원 리 는 얼마나 알 고 있 습 니까?
synchronized
자바 프로 그래 밍 의 중요 한 키워드 이자 다 중 스 레 드 프로 그래 밍 에서 없어 서 는 안 되 거나 없어 서 는 안 되 는 사람 입 니 다.본 고 는 그것 의 사용 과 자물쇠 의 중요 한 개념 에 대해 분석 하고 자 한다.사용 및 원리
synchronized 는 중량급 자물쇠 로 동기 화 작업 을 실현 합 니 다. 자바 대상 자물쇠 에는 세 가지 사용 방식 이 있 습 니 다.
쓰다
코드 에서 사용 하 는 방법 은 다음 과 같다.
일반 방법 사용:
/**
* :yt
* :t
*/
public class SynchronizedMethodDemo{
public synchronized void demo(){
// ......
}
}
정적 방법 사용:
/**
* :yt
* :t
*/
public class SynchronizedMethodDemo{
public synchronized static void staticDemo(){
// ......
}
}
코드 블록 에서 사용:
/**
* :yt
* :y
*/
public class SynchronizedDemo{
public void demo(){
synchronized (SynchronizedDemo.class){
// ......
}
}
}
실현 원리
방법 과 코드 블록 의 실현 원 리 는 서로 다른 방식 을 사용한다.
부호 블록
대상 마다 하나의
monitor
대상 이 있 고 코드 블록 {}
에 monitorenter
과 monitorexit
명령 이 삽입 된다.monitorenter
명령 을 실행 할 때 monitor
대상 에 들 어가 자 물 쇠 를 가 져 오고 monitorexit
명령 을 실행 할 때 monitor
대상 에서 자 물 쇠 를 방출 합 니 다.같은 시각 에 하나의 스 레 드 만 monitorenter
에 들 어 갈 수 있다.먼저
SynchronizedDemo.java
사용 javac SynchronizedDemo.java
명령 을 SynchronizedDemo.class
로 컴 파일 합 니 다.그리고 javap -c SynchronizedDemo.class
바이트 코드 를 역 컴 파일 합 니 다.Compiled from "SynchronizedDemo.java"
public class SynchronizedDemo {
public SynchronizedDemo();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."":()V
4: return
public void demo();
Code:
0: ldc #2 // class SynchronizedDemo
2: dup
3: astore_1
4: monitorenter // monitor
5: aload_1
6: monitorexit // monitor
7: goto 15
10: astore_2
11: aload_1
12: monitorexit // monitor
13: aload_2
14: athrow
15: return
Exception table:
from to target type
5 7 10 any
10 13 10 any
}
위 에서 인 코딩 된 코드 는 두 개의
monitorexit
명령 이 있 고 하 나 는 이상 한 위치 에 삽입 되 며 하 나 는 방법 끝 위치 에 삽입 된다.방법.
방법 중의
synchronized
은 코드 블록 에서 실현 되 는 방식 과 달리 방법 에 ACC_SYNCHRONIZED
라 는 표 지 를 추가 합 니 다. 호출 방법 이 있 을 때 먼저 ACC_SYNCHRONIZED
표지 가 있 는 지 확인 하고 존재 하면 monitor
대상, 호출 monitorenter
과 monitorexit
명령 을 받 습 니 다.javap -v -c SynchronizedMethodDemo.class
명령 을 통 해 클래스 를 역 컴 파일 SynchronizedMethodDemo
합 니 다.-v
매개 변 수 는 -verbose
출력 반 컴 파일 의 추가 정 보 를 나타 낸다.다음은 일반적인 방법 을 역 컴 파일 하 는 것 을 예 로 들 자.Classfile /E:/SynchronizedMethodDemo.class
Last modified 2020-6-28; size 381 bytes
MD5 checksum 55ca2bbd9b6939bbd515c3ad9e59d10c
Compiled from "SynchronizedMethodDemo.java"
public class SynchronizedMethodDemo
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #5.#13 // java/lang/Object."":()V
#2 = Fieldref #14.#15 // java/lang/System.out:Ljava/io/PrintStream;
#3 = Methodref #16.#17 // java/io/PrintStream.println:()V
#4 = Class #18 // SynchronizedMethodDemo
#5 = Class #19 // java/lang/Object
#6 = Utf8
#7 = Utf8 ()V
#8 = Utf8 Code
#9 = Utf8 LineNumberTable
#10 = Utf8 demo
#11 = Utf8 SourceFile
#12 = Utf8 SynchronizedMethodDemo.java
#13 = NameAndType #6:#7 // "":()V
#14 = Class #20 // java/lang/System
#15 = NameAndType #21:#22 // out:Ljava/io/PrintStream;
#16 = Class #23 // java/io/PrintStream
#17 = NameAndType #24:#7 // println:()V
#18 = Utf8 SynchronizedMethodDemo
#19 = Utf8 java/lang/Object
#20 = Utf8 java/lang/System
#21 = Utf8 out
#22 = Utf8 Ljava/io/PrintStream;
#23 = Utf8 java/io/PrintStream
#24 = Utf8 println
{
public SynchronizedMethodDemo();
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 5: 0
public synchronized void demo();
descriptor: ()V
flags: ACC_PUBLIC, ACC_SYNCHRONIZED // ACC_SYNCHRONIZED
Code:
stack=1, locals=1, args_size=1
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: invokevirtual #3 // Method java/io/PrintStream.println:()V
6: return
LineNumberTable:
line 8: 0
line 10: 6
}
SourceFile: "SynchronizedMethodDemo.java"
위 에서 코드 블록 과 방법의 실현 방식 에 대해 탐구 했다.
monitorenter
과 monitorexit
명령 을 추가 합 니 다.ACC_SYNCHRONIZED
함으로써 호출 여 부 를 결정 한다 monitor
.Java 개체 헤더
synchronized
잠 긴 관련 데 이 터 는 자바 대상 머리 에 저 장 됩 니 다.자바 개체 헤드 가 가리 키 는 핫 스 팟 가상 머 신의 대상 헤드 는 2 글자 너비 또는 3 글자 너비 저장 대상 헤드 를 사용한다.Mark Word
라 고 한다.Java 개체 헤더 Mark Word 저장 내용:
저장 내용
표지 비트
상태.
대상 의 hashCode, GC 세대 구분 연령
01
자물쇠 없 음
스 택 의 잠 금 기록 을 가리 키 는 지침
00
경량급 자물쇠
헤비급 자 물 쇠 를 가리 키 는 지침
10
헤비급 자물쇠
비다
11
GC 태그
스 레 드 ID, Epoch (타임 스탬프), GC 세대 구분 연령
01
편향 자물쇠
자물쇠 업그레이드
synchronized 는 헤비급 잠 금 이 라 고 하지만 자바 SE 1.6 은 이 잠 금 의 성능 을 최적화 하기 위해 잠 금 의 성능 소 모 를 줄 이 고 도입
과
한다.자물쇠 의 높 고 낮 음 단 계 는
→
→
→
이다.그 중에서 자물쇠 의 업 그 레이 드 는 거 스 를 수 없고 낮은 것 에서 고급 으로 만 올 라 갈 수 있 으 며 높 은 것 에서 낮은 것 으로 내 려 갈 수 없다.
편향 자물쇠
편향 잠 금 은 다 중 스 레 드 경쟁 없 이 프로그램의 운행 성능 을 향상 시 키 기 위해 사용 되 는 잠 금 이다.
Mark Word
에 하나의 값 을 저장 하여 편향 잠 금 여 부 를 표시 합 니 다. 32 비트 가상 컴퓨터 와 64 비트 가상 컴퓨터 에서 모두 하나의 바이트 로 저장 되 고 0 은 비 편향 잠 금 이 며 1 은 편향 잠 금 입 니 다.첫 번 째 스 레 드 에서 편향 잠 금 을 가 져 올 때
Mark Word
의 편향 잠 금 표 지 를 1 로 설정 하고 CAS 동작 으로 이 스 레 드 의 ID 를 기록 합 니 다.편향 잠 금 스 레 드 를 가 져 와 잠 금 가 져 오기 에 다시 들 어 갈 때 Mark Word
현재 스 레 드 ID 가 저장 되 어 있 는 지 판단 하기 만 하면 됩 니 다. 그렇다면 잠 금 가 져 오기 동작 을 다시 하지 않 고 이 자 물 쇠 를 직접 가지 고 있 습 니 다.잠 금 해제
다른 스 레 드 가 나타 나 면 편향 자 물 쇠 를 가 져 와 경쟁 상태 에 있 게 하려 고 시도 하면 현재 편향 자 물 쇠 는 취 소 됩 니 다.편향 잠 금 을 해제 할 때 우선 편향 잠 금 이 있 는 스 레 드 를 일시 정지 하고 스 레 드 ID 를 비 워 둔 다음 이 스 레 드 가 살아 있 는 지 확인 합 니 다.
코드 가 다 중 스 레 드 접근 에서 반드시 실 행 될 것 이 라 고 확 정 했 을 때 이 때 편향 잠 금 은 장점 을 발휘 하지 못 합 니 다. 편향 잠 금 을 계속 사용 하면 너무 번 거 롭 고 시스템 에 불필요 한 성능 비용 을 가 져 다 줄 수 있 습 니 다. 이때 JVM 파라미터
-XX:BiasedLocking=false
를 설정 하여 편향 잠 금 을 닫 을 수 있 습 니 다.경량급 자물쇠
코드 가 동기 블록 에 들 어 갈 때 대상 헤드 가 잠 겨 있 지 않 으 면 JVM 은 현재 스 레 드 의 스 택 정 에
공간 을 만 들 고 잠 겨 있 는 대상 헤드 Mark Word
를
에 복사 합 니 다. 이 복사 한 Mark Word
을 Displaced Mark Word
이 라 고 합 니 다.그리고 CAS 동작 을 사용 하여 잠 금 대상 헤드 의 Mark Word
를 가리 키 는
지침 으로 업데이트 합 니 다.업데이트 에 성공 하면 현재 스 레 드 는 자 물 쇠 를 얻 습 니 다. 실패 하면 JVM 은 먼저 잠 금 대상 Mark Word
이 현재 스 레 드 를 가리 키 는 지, 현재 스 레 드 를 가리 키 는 지 확인 합 니 다. 그러면 현재 스 레 드 는 자 물 쇠 를 가지 고 있 습 니 다. 그렇지 않 으 면 다 중 스 레 드 경쟁 이 존재 합 니 다그래서 이 과정 은 CPU 를 소모 하 는 과정 이다.경량급 자물쇠 가 경쟁 상태 에 존재 하고 경량급 자 물 쇠 를 자전 적 으로 가 져 오 는 데 실 패 했 을 때 경량급 자 물 쇠 는 중량급 자물쇠 로 팽창 하고 자물쇠 대상 Mark Word
은 중량급 자 물 쇠 를 가리 키 는 지침 으로 업데이트 되 며 자 물 쇠 를 가 져 오 는 스 레 드 가 차단 상태 에 들 어가 기 를 기다린다.자 물 쇠 를 풀다
경량급 잠 금 해 제 는 CAS 작업 으로
를 Mark Word
로 교체 하 는 것 으로, 교체 에 성공 하면 동기 화 작업 이 완료 됐다 는 뜻 이다.실패 하면 다른 경쟁 스 레 드 가 이 경량급 자 물 쇠 를 가 져 오 려 고 시 도 했 음 을 나타 낸다. 자 물 쇠 를 풀 면서 다른 막 힌 스 레 드 를 깨 우 고 깨 워 진 스 레 드 는 다시 경쟁 자 물 쇠 를 가 져 가 야 한다.총결산
분석
synchronized
의 사용 과 자바 SE 1.6 업그레이드 최적화 잠 금 후의 디자인 을 통 해 알 수 있 듯 이 주로 해결 하 는 것 은 2 급 상대 적 으로 가 벼 운 편향 잠 금 과 경량급 잠 금 을 더 넣 어 중량급 잠 금 의 성능 소 모 를 최적화 하 는 것 이지 만 이것 이 반드시 최적화 역할 을 하 는 것 은 아니다.주로 대부분 상황 에서 다 중 스 레 드 경쟁 과 같은 스 레 드 가 여러 번 자 물 쇠 를 얻 는 최적화 가 존재 하지 않 는 다 는 것 을 해결 하 는 것 도 평소에 인 코딩 에서 많이 관찰 하고 반성 한 평가 방안 이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.