본문 바로가기
Computer Science/운영체제

쓰레드 세이프(Tread Safe)

by eunnnn 2023. 3. 19.

멀티 스레드 환경에서의 스레드 세이프 (Thread Safe)

쓰레드 세이프(Thread Safe)란 멀티 스레드 프로그래밍 과정에서 어떤 공유 자원(함수, 변수, 객체 등)에 여러 스레드가 동시에 접근해도 프로그램 실행에 문제가 없는 상태를 말한다.

 

Thread Safe를 지키기 위한 조건

  • Re-entrancy
    어떤 함수가 한 스레드에 의해 호출되어 실행 중일 때, 다른 스레드가 그 함수를 호출하더라도 그 결과가 각각에게 올바르게 주어져야한다.
  • Thread-local Storage
    공유 자원의 사용을 최대한 줄여 각각의 스레드에서만 접근 가능한 저장소들을 사용함으로써 동시 접근을 막는다.
  • Mutual exclusion
    공유 자원을 꼭 사용해야 할 경우 해당 자원의 접근을 락으로 통제한다.
  • Atomic Operations
    공유 자원에 접근할 때 원자 연산을 이용하거나 '원자적'으로 정의 접근 방법을 사용한다.

 

자바 환경에서 Thread Safe하게 멀티 스레드 환경 설계 하는 법

1. synchronized 키워드 사용 (자원 자체에 Lock을 거는 방법)

public class SyncSingleton {
    private int count = 0;

   // synchronized method
   public synchronized int increase() {
        return ++count;
    }

    // synchronized statement 로 구현하여 해당 블럭에 한번에 한 쓰레드만 접근할 수 있도록 한다.
    public int increase() {
        synchronized(this) {
            return ++count;
        }
    }
}

synchronized 로 선언된 블럭은 한 스레드만 접근할 수 있다한 스레드에 의해서 실행 중인 메서드에 다른 스레드가 접근하는 경우 블로킹된다. synchronized 키워드를 사용하면 간편하지만 최적화가 되어있지 않아서 다른 방법들에 비해 성능이 떨어지는 단점이 있다.

해당 키워드를 사용하는 방법 외에도 직접 Lock 객체를 명시적으로 생성하여 자원을 제어하는 방법 또한 존재한다.

 

2. java.util.concurrent 패키지 하위의 클래스 사용

import java.util.concurrent.atomic.AtomicInteger;

public class ReentrantLockSingleton {

    private AtomicInteger count = new AtomicInteger(0);

    public int increase() {
        return count.incrementAndGet();
    }
}

"java.util.concurrent.atomic" 패키지에서는 thread-safe 한 클래스 타입 들을 제공한다. atomic 타입은 해당 타입으로 선언한 단일 변수에 대하여 atomic operations 를 지원한다. 해당 타입은 사용 시에 내부적으로 CAS (Compare And Swap) 알고리즘을 사용하여 값을 비교하는 방식으로 동기화를 적용한다. 

 

3. Thread-Safe하게 설계 된 Singleton 패턴을 사용

일반적으로 구현하는 Singleton Pattern은 Thread-safe 하지 않기 때문에, Thread-safe 하게 설계 된 Singleton 패턴을 사용해야 한다.

  • Holder에 의한 초기화 방법
    클래스 안에서 클래스(Holder)를 두어 JVM Class Loader 매커니즘을 이용하여 초기화의 책임을 JVM으로 이동시킨다.
  • Syncronized 키워드를 사용하여 초기화 한 싱글톤 인스턴스 사용 (게으른 초기화)
  • Double-Check loading
    싱글톤 클래스의 인스턴스의 null 체크를 synchronized 블록 밖에서 한 번 검사하여 이미 인스턴스가 생성되어 있으면 동기화 할 필요 없이 바로 빠르게 그 인스턴스를 반환한다. 이후 synchronized 블록 내에서 다시 체크하여 싱글톤 클래스의 인스턴스가 생성되지 않았을 때, 여러 쓰레드에서 여러 개의 인스턴스를 중복 생성하는 일이 없이 하나의 인스턴스만 생성하도록 한다.
  • Enum 사용
    Enum자체가 Thread-safe하게 구현되어 있음.

 

'Computer Science > 운영체제' 카테고리의 다른 글

프로세스/스레드 동기화  (0) 2023.03.19
Sync vs Async & Block vs Non-Block  (0) 2023.03.19
캐시 메모리  (0) 2023.03.18
가상 메모리(Virtual Memory)  (0) 2023.03.18
교착상태와 기아상태  (1) 2023.03.18