[Java] 동시성 제어 2탄 - 세마포어(Semaphore)

2025. 12. 28. 21:53·Teck Stack/Java

개요


[Java] 동시성 제어 1탄 - Lock

 

[Java] 동시성 제어 1탄 - Lock

개요멀티 스레딩 환경에서 발생할 수 있는 동시성 문제 상황을 살펴보고, Java에서 이를 어떻게 제어할 수 있는지 알아보고자 합니다. 동시성 제어에는 다양한 방법이 존재하지만, 이번 포스팅에

taetae99.tistory.com

 

이전 게시글에 이어서, Java 환경에서 동시성을 제어하는 방법에 대해 작성하겠습니다.

 

이번 게시글에서는 세마포어를 활용한 동시성 제어를 다루고 있습니다.

 

 

 

세마포어란?


세마포어는 동시에 실행할 수 있는 스레드 수를 제한하는 데 사용합니다.

 

즉, 자원에 대한 접근을 일정 수준으로 제한하고 싶을 때 사용할 수 있습니다.

 

세마포어의 동작은 다음과 같습니다.

  1. 세마포어에서 퍼밋을 획득한다. ( permit-- )
  2. 코드를 실행한다.
  3. 세마포어에 퍼밋을 반환한다. ( permit++ )

 

여기서 퍼밋(permit)이란 Java의 세마포어 구현체에서 사용하는 용어로, 허용 가능한 숫자를 의미합니다.

java semaphore의 permit

 

예를 들어, 퍼밋이 3이면 동시에 실행할 수 있는 스레드 수는 3개입니다.

 

각 스레드는 세마포어에서 퍼밋을 획득한 뒤에 코드를 실행할 수 있습니다.

 

남은 퍼밋의 개수가 0보다 작거나 같아지면, 새롭게 진입하려는 스레드는 실행되지 않고 먼저 퍼밋을 획득했던 스레드가 퍼밋을 반환할 때까지 대기하게 됩니다.

 

이때 다른 스레드가 signal을 호출하면 세마포어의 퍼밋이 1 증가하고, 해당 스레드는 대기 상태에서 깨어나 퍼밋을 획득할 수 있습니다.

 

 

세마포어의 연산

세마포어에서 퍼밋을 획득하는 연산을 P 연산 또는 wait 연산이라고 부르며,

 

퍼밋을 반환하는 연산을 V 연산 또는 signal 연산이라고 부릅니다.

 

 

잠금과 세마포어의 차이


세마포어를 접했을 때 잠금과 유사한 부분이 많다고 생각했습니다.

 

실제로 잠금과 세마포어는 둘 다 여러 스레드의 접근을 제어한다는 공통점을 가지고 있어,

동시에 접근할 수 있는 스레드 수만 다른 거 아닐까?라는 의문이 들기도 합니다.

 

하지만 결론부터 말하자면, 잠금과 세마포어는 서로 다른 목적과 역할을 갖고 있습니다.

 

그렇다면 구체적으로 어떤 차이가 있는지, 자세히 알아보겠습니다.

 

잠금

잠금

화장실에 칸이 하나뿐이라고 가정해 보겠습니다.

 

한 사람이 화장실을 사용하려면, 칸에 들어가 문을 잠그게 됩니다.

 

이때 다른 사람들은, 사용 중인 사람이 잠금을 해제하고 화장실에 나올 때까지 대기해야 합니다.

 

 

이처럼 잠금은 하나의 스레드(사람 1명)만이 임계 영역(화장실)에 들어가 공유 자원을 획득할 수 있도록 합니다.

 

또한, 잠금을 걸었던 특정 스레드만이 임계 영역에서 나갈 때 잠금을 해제할 수 있습니다.

 

 

세마포어

세마포어

 

세마포어는 주차장의 잔여 공간 개수를 나타내는 전광판으로 비유할 수 있습니다.

 

주차 공간이 3개인 경우, 잔여 공간은 3개입니다.


자동차 1대가 주차하면 잔여 공간은 2개가 되고, 자동차 3대가 주차하면 잔여 공간은 0개가 됩니다.

 

이처럼 세마포어는 현재 사용 가능한 자원의 개수를 관리합니다.

 

차이점

잠금과의 가장 큰 차이는 잠금 해제 방식에 있습니다.

 

  • 잠금은 락을 획득한 스레드만 해제할 수 있습니다.
    • 화장실에 들어간 사람만이, 화장실에서 나오면서 잠금을 해제할 수 있습니다.
  • 세마포어는 락을 획득하지 않은 스레드도 signal을 호출해 자원을 반납할 수 있습니다.
    • 1번에 주차한 자동차가 나가더라도, 어느 공간이 비었는지가 중요한 것이 아니라 전체 주차 공간 중 사용 가능한 자리가 하나 늘어났다는 점이 핵심입니다.

 

세마포어의 종류


세마포어에는 두 종류가 있습니다.

 

허용 가능한 숫자에 따라 다음과 같이 분류할 수 있습니다.

 

  • 이진 세마포어(binary)
    • 동시에 접근할 수 있는 스레드가 1개인 세마포어를 의미합니다.
  • 계수 세마포어(counting)
    • 지정한 수만큼 접근이 가능한 세마포어를 의미합니다.

 

 

세마포어를 언제 쓸까?


세마포어는 자원에 대한 접근을 일정 수준으로 제한할 때 사용한다고 했습니다.

 

예를 들어, 외부 서비스에 대한 동시 요청 수를 일정 개수로 제한하고 싶을 때 세마포어를 사용할 수 있습니다.

동시 요청 수 초과

외부 연동 시스템이 처리할 수 있는 동시 요청의 수가 50개라고 가정하겠습니다.

 

하지만, 현재 서비스에 사용자가 몰려 100개의 결제 요청이 한 번에 들어왔습니다.

 

외부 결제 API는 갑작스럽게 많은 요청을 받았기에 429 요청을 반환하거나, 장애가 발생할 수 있습니다.

 

 

외부 서버 요청이 지연됨에 따라 우리 서버의 스레드도 응답을 기다리게 되며 서비스가 마비될 수 있습니다.

 

이러한 상황을 방지하기 위해, 세마포어를 사용해 외부 API로 전달되는 동시 요청 수를 제한할 수 있습니다.

세마포어로 동시 요청 수 제한

 

 

다음은 결제 서비스에서 10개의 세마포어를 사용하여 외부 결제를 처리하는 코드입니다.

public class PaymentService {
    private final Semaphore semaphore = new Semaphore(10);

    public void pay() {
        try {
            semaphore.acquire();
        } catch (InterruptedException e) {
            throw new RuntimeException("Too Many Request" + e);
        }
        try{
            //외부 PG 연동
        } finally {
            semaphore.release();
        }
    }
}

 

 

 

참고


[OS] 세마포어(Semaphore) vs 뮤텍스(Mutex) 차이
BJ.9 스핀락(spinlock) 뮤텍스(mutex) 세마포(semaphore) 각각 특징과 차이 설명! 뮤텍스는 바이너리 세마포가 아니에요

주니어 백엔드 개발자가 반드시 알아야 할 실무 지식 - 최범균 저

반응형

'Teck Stack > Java' 카테고리의 다른 글

[Java] 동시성 제어 1탄 - Lock  (1) 2025.12.27
[Java] 일급 컬렉션(First Class Collection)이란?  (0) 2025.10.25
[JAVA] Static은 언제 사용할까?  (0) 2025.10.24
[Java] Error와 Exception  (0) 2025.10.08
'Teck Stack/Java' 카테고리의 다른 글
  • [Java] 동시성 제어 1탄 - Lock
  • [Java] 일급 컬렉션(First Class Collection)이란?
  • [JAVA] Static은 언제 사용할까?
  • [Java] Error와 Exception
taetae99
taetae99
우직하게 개발하기
    반응형
  • taetae99
    코드 대장간
    taetae99
  • 전체
    오늘
    어제
    • 분류 전체보기
      • Teck Stack
        • Java
        • Spring
        • DB
        • Redis
        • SpringSecurity
        • Docker
        • HTML
        • AWS
      • 우아한테크코스
      • CS & Architecture
        • DDD
        • CS
        • 디자인 패턴
      • 트러블 슈팅
      • 알고리즘
        • 프로그래머스
        • 백준
      • 프로젝트
        • Board 프로젝트
      • 기타
      • 대회 및 후기
  • 인기 글

  • hELLO· Designed By정상우.v4.10.3
taetae99
[Java] 동시성 제어 2탄 - 세마포어(Semaphore)
상단으로

티스토리툴바