-
싱글톤 패턴Language/Java 2023. 11. 30. 00:01
책을 보다가 싱글톤 패턴에 대한 코드를 봤는데, 내가 사용하는 코드와 다른 방식으로 설명을 해서 챗봇에게 책에서 본 코드와 내가 사용하는 코드를 비교해서 설명해달라고 부탁했다.
결론부터 얘기해보자면 두개는 다른 패턴의 싱글톤 구현 코드였고, 내가 사용하던 코드에는 심지어 문제가 있었다. 🙊
스레드 안전성이 없다고 한다,
관련해서 두 가지 문제점을 지적받았는데,
첫 번째로
synchronized
블록을 사용하지 않았기 때문에 여러 스레드가 동시에 getInstance()에 접근하게 된다면 Hello 인스턴스가 여러번 생성될 수 있는 문제가 있었고,두 번째로는
멀티스레드 환경에서 Hello 인스턴스를 생성한 후 다른 스레드가 이것을 볼 수 없는 경우가 발생할 수 있다고 한다. 인스턴스 생성 과정에서 컴파일러 최적화와 CPU 캐시 메모리의 동기화 문제 때문이었다. 이 문제를 해결하려면
volatile
키워드를 사용해서 INSTANCE 변수를 생성하면 된다.volatile
키워드는 변수가 항상 메인 메모리에서 읽고 쓰여야 함을 나타내고, 이를 통해 모든 스레드가 항상 최신 값을 볼 수 있도록 한다고 한다.이제 내가 사용하던 문제가 있는 코드를 소개하자면 다음과 같다.
public class Hello { private static Hello INSTANCE; private Hello() {} public static Hello getInstance() { if (INSTANCE == null) INSTANCE = new Hello(); return INSTANCE; } }
이거였고, 코칭 받아 수정된 코드는 다음과 같다.
class Hello { private static volatile Hello INSTANCE; private Hello() {} public static Hello getInstance() { if (INSTANCE == null) { synchronized (Hello.class) { if (INSTANCE == null) INSTANCE = new Hello(); } } return INSTANCE; } }
그리고 책에서 본 코드는
class Hello { public static class SingleInstanceHolder { private static final Hello INSTANCE = new Hello(); } public static Hello getInstance() { return SingleInstanceHolder.INSTANCE; } }
이거였다.
내가 사용하는 코드는
Double-checked Locking
패턴을 사용한 방식이고 (약간 잘못 사용하고 있었지만 🥲)책에서 본 코드는
Initialization on Demand Holder
패턴을 사용한 방식이라고 한다. 이 패턴을 사용하면 간단하게 스레드 안전성을 보장받을 수 있다.챗봇은
Initialization on Demand Holder
패턴의 단점으로 코드 가독성의 어려움을 꼽았는데,내가 봤을 땐
Double-checked Locking
패턴이 더 어려운 것 같다..ㅋㅋㅋ ㅠㅠ싱글톤 패턴을 얼마나 사용 하게 될 지는 모르겠지만.. 그래도 잘못 알고있었던 부분에 대해 바로 잡을 수 있어서 좋은 기회였다고 생각한다. 🤓
'Language > Java' 카테고리의 다른 글
Optional (0) 2023.11.30 자바 메모리 모델 Java Memory Model (0) 2023.11.30 OkHttp3 라이브러리 사용 with 비동기 (0) 2023.11.29 Thread (0) 2023.11.29 제네릭 Generic 프로그래밍 (0) 2023.11.28