설명
Double-checked locking으로 지연 초기화를 구현하면서 대상 필드를 volatile로 선언하지 않으면 다른 스레드가 완전히 초기화되지 않은 객체를 관찰할 수 있습니다. 보안 설정, 인증 상태, 캐시 싱글턴처럼 일관성이 중요한 객체에서는 예측하기 어려운 동작으로 이어질 수 있습니다.
잠재적 영향
- 초기화되지 않은 보안 상태 사용
- 인증 또는 권한 판단의 불안정한 동작
- 간헐적인 장애와 재현 어려운 동시성 오류
해결 방법
- double-checked locking 대상 필드를 Java에서는
volatile, Kotlin에서는@Volatile로 선언합니다. - 가능하면 initialization-on-demand holder, enum singleton, 의존성 주입 컨테이너를 사용합니다.
- 보안 상태 객체는 불변 객체로 구성합니다.
예시
변경 전
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로 선언합니다.