안전하지 않은 Double-Checked Locking

안전하지 않은 double-checked locking 초기화

설명

Double-checked locking으로 지연 초기화를 구현하면서 대상 필드를 volatile로 선언하지 않으면 다른 스레드가 완전히 초기화되지 않은 객체를 관찰할 수 있습니다. 보안 설정, 인증 상태, 캐시 싱글턴처럼 일관성이 중요한 객체에서는 예측하기 어려운 동작으로 이어질 수 있습니다.

잠재적 영향

  • 초기화되지 않은 보안 상태 사용
  • 인증 또는 권한 판단의 불안정한 동작
  • 간헐적인 장애와 재현 어려운 동시성 오류

해결 방법

  1. double-checked locking 대상 필드를 Java에서는 volatile, Kotlin에서는 @Volatile로 선언합니다.
  2. 가능하면 initialization-on-demand holder, enum singleton, 의존성 주입 컨테이너를 사용합니다.
  3. 보안 상태 객체는 불변 객체로 구성합니다.

예시

변경 전

java
private static Config instance;

public static Config getInstance() {
    if (instance == null) {
        synchronized (Config.class) {
            if (instance == null) {
                instance = new Config();
            }
        }
    }
    return instance;
}

변경 후

java
private static volatile Config instance;

설명:

  • 변경 전: volatile 없이 double-checked locking으로 객체를 초기화하면 다른 스레드가 완전히 초기화되지 않은 객체를 관찰할 수 있습니다.
  • 변경 후: double-checked locking 대상 필드를 volatile로 선언합니다.

참조