[Java] Synchronized / ReentrantLock 차이

2025. 3. 6. 10:57·Java | Spring
728x90

스레드 동기화

스레드 동기화 개념

  • 스레드 동기화 : 멀티 스레드 환경에서 여러 스레드가 한 공유 자원에 동시에 접근하지 못하도록 막는 것
    • 임계 영역 : 공유 데이터가 사용되어 동기화가 필요한 부분
    • 상호 배제 : 임계 영역이 오직 한 스레드에 의해 배타독점적으로 사용되도록 하는 기술
      • 임계 영역에 먼저 진입한 스레드가 임계 영역의 실행을 끝낼 때까지 다른 스레드가 진입하지 못하도록 보장

스레드 동기화의 필요성

  • 예시 : 재고가 1개인 제품에 대해 동시다발적으로 주문이 10건 인입되었을 때, 남은 재고가 1개임에도 불구하고 주문 10건이 모두 성공하는 상황이 발생
    → 공유 데이터가 훼손되는 문제 발생

 

synchronized 키워드

  • Synchronized (임계 영역 설정과 락 권한)
public synchronized void insertOrder(OrderDto orderDto) {...}
  • 메서드 전체를 임계 영역으로 설정
    • 임계 영역으로 지정할 메서드의 반환 타입 앞에 `synchronized` 키워드 추가
    • 설정한 메서드가 호출되었을 때 메서드를 실행할 스레드는 메서드가 포함된 객체의 락 (Lock) 을 획득
    • 다시 락이 반납되기 전까지 다른 스레드는 해당 스레드를 실행하지 못함
public void insertOrder(OrderDto orderDto) {
    synchronized (this) {
        // ...
    }
}
  • 특정 코드 블록을 임계 영역으로 설정
    • 임계 영역으로 지정할 코드 상단에 `synchronized` 키워드 추가
    • 예제처럼 소괄호 내에 해당 영역이 포함된 객체의 참조 입력 시 참조 변수 객체의 락 (Lock) 을 사용하게 됨
private final Object lock = new Object();

public void insertOrder1(OrderDto orderDto) {
    synchronized (lock) {
        // ...
    }
}

public void insertOrder2(OrderDto orderDto) {
    synchronized (lock) {
        // ...
    }
}
  • 예제처럼 각각 다른 메서드에서도 한번에 한 스레드만 진입가능해야 할 경우 락 (Lock) 객체를 지정하여 사용할 수 있음
    • 동시에 `insertOrder1` 에 진입한 스레드와 `insertOrder2` 에 진입한 스레드가 있을 경우 임계 영역을 먼저 진입한 스레드가 작업을 마칠 때까지 다른 스레드는 대기 상태가 됨
private final ConcurrentHashMap<String, Object> lockMap = new ConcurrentHashMap<>();

public void insertOrder1(OrderDto orderDto) {

    Object lock = lockMap.computeIfAbsent(key, k -> new Object());

    synchronized (lock) {
        // ...
    }
}

public void insertOrder2(OrderDto orderDto) {

    Object lock = lockMap.computeIfAbsent(key, k -> new Object());

    synchronized (lock) {
        // ...
    }
}
  • 특정 키 값에 대해 동일한 값으로 메서드에 진입하는 경우에만 락 (Lock) 을 걸어야 할 경우
    • `ConcurrentHashMap` 타입의 map 에 해당 키 값이 존재하는 경우에는 대기
    • 키가 존재하지 않는 경우에는 새로운 Object 객체를 만들고 진입

 

 

 

 

 

ReentrantLock

  • ReentrantLock : 특정 시간을 대기하다 무시하고 지나가거나 Lock 잡는 순서를 보장해야 하는 경우 등 Lock에 대해 다양하게 관리하거나 컨트롤해야 할 경우에 사용
  • 사용방법
// Constructor
ReentrantLock()
ReentrantLock(boolean fair)
  • fair 을 true 로 설정 시 가장 오래 기다린 스레드가 Lock 을 얻을 수 있도록 공정하게 처리
    • 단, 스레드 대기 시간을 확인하는 과정이 필요하므로 성능이 저하될 수 있음
// Method
void lock() // lock 잠금
void unlock() // lock 해제
boolean isLocked() // lock이 잠겼는지 확인
boolean tryLock() // lock polling
boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException
  • `synchronized` 블럭과 달리, 수동으로(명시적으로) Lock 을 잠그고 해제해야 함

 

@Synchronized 어노테이션

private static final Object LOCK = new Object();

@Synchronized("LOCK")
public void insertOrder() {...}

@Synchronized("LOCK")
public void updateOrder() {...}

@Synchronized
public void deleteOrder() {...}
  • `@Synchronized` : 메소드에 사용되는 어노테이션으로 기본적으로 지원되는 `synchronized` 키워드보다 더 세세한 설정이 가능
    • `synchronized` 키워드는 static 혹은 instance 단위로 락을 잠금
    • `@Synchronized` 어노테이션은 파라미터로 입력받는 Object 단위로 락을 잠금
      • 파라미터로 아무것도 입력하지 않으면 어노테이션이 사용된 메소드 단위로 락
    • `insertOrder` 와 `updateOrder` 는 두 메소드가 동시에 호출되었을 경우 한 번에 한 스레드만이 메소드에 진입할 수 있고 다른 스레드는 대기해야함
    • `deleteOrder` 는 두 스레드가 동시에 호출했을 경우 한 번에 한 스레드만이 진입할 수 있음
728x90
저작자표시 비영리 변경금지 (새창열림)

'Java | Spring' 카테고리의 다른 글

[Spring] @ControllerAdvice, @RestControllerAdvice  (0) 2025.03.09
[Spring] @RequestParam, @RequestBody, @ModelAttribute  (1) 2025.03.09
[Java] 제네릭 (Generics)  (2) 2025.03.08
[Java] 다형성과 캐스팅  (0) 2025.03.08
[Java] Builder 패턴과 @Builder 어노테이션  (0) 2025.03.07
'Java | Spring' 카테고리의 다른 글
  • [Spring] @RequestParam, @RequestBody, @ModelAttribute
  • [Java] 제네릭 (Generics)
  • [Java] 다형성과 캐스팅
  • [Java] Builder 패턴과 @Builder 어노테이션
cyyy
cyyy
    250x250
  • cyyy
    Dev Log
    cyyy
  • 전체
    오늘
    어제
    • 분류 전체보기 (71)
      • Web | Network (14)
      • JavaScript (17)
      • Node.js (13)
      • Java | Spring (17)
        • GitHub Clone Project (6)
      • DB (4)
      • Linux (4)
      • AWS (2)
      • IDE (0)
  • 최근 글

  • 인기 글

  • 태그

    Spring
    Linux
    promise
    노드
    bcrypt
    프로토콜
    Java
    프로토타입
    비동기
    네트워크
    자바스크립트
    prototype
    Database
    Network
    node.js
    스프링
    db
    spring boot
    github clone
    JavaScript
  • 링크

    • Notion Log
  • hELLO· Designed By정상우.v4.10.3
cyyy
[Java] Synchronized / ReentrantLock 차이
상단으로

티스토리툴바