개발쿠키

(디자인패턴)싱글톤 패턴(java) 본문

개발/그냥 코딩

(디자인패턴)싱글톤 패턴(java)

쿠키와개발 2023. 4. 10. 16:18

싱글톤이란?

싱글톤 패턴이란 클래스에 대한 인스턴스를 오직 한개만 생성하여 글로벌하게 사용하는 패턴을 말한다.

 

우리는 보통 객체를 생성할 때 new Class이름() 이런식으로 객체를 생성하지만 싱글톤 방식은 인스턴스를 오직 한개만 생성해야 하기 때문에 생성자 자체를 private로 설정하고 해당 Class에서 제공하는 getInstance와 같은 메소드로 받아온다.

싱글톤 구현 방식은 다양한 방식이 있지만 쉽고 간단 예제들로 살펴보자

이른 초기화(eager) 방식

이른 초기화 방식은 클래스가 로드 될 때 필드값들을 초기화 하여 미리 만들어 놓는 방식이다.

해당 방식은 클래스를 자주 사용하거나 할 때 즉 미리 만들어 놔도 상관없는 환경일 때 쓰면 좋다. 하지만 자주 쓰지 않을 때는 메모리만 낭비할 수 있다는 단점이 있다.

//이른 초기화
public class SingleEx {
    private static final SingleEx singleEx = new SingleEx();
    private int val = 1;

    public static SingleEx getSingleEx(){
        return singleEx;
    }

    public int getVal() {
        return val;
    }

    public void setVal(int val) {
        this.val = val;
    }
}

지연 초기화(lazy) 방식

해당 방식은 두가지 방식이 있다. 코드를 먼저 보자

public class SingleEx2 {
    private static SingleEx2 singleEx;
    private int val = 2;

//  동기화 처리가 필요하기 때문에 성능 이슈가 있을 수 있다.
    public static synchronized SingleEx2 getSingleEx2(){
        if (singleEx == null){
            singleEx = new SingleEx2();
        }
        return singleEx;
    }

    public int getVal() {
        return val;
    }

    public void setVal(int val) {
        this.val = val;
    }
}

위 코드는 getSingleEx2 메소드를 호출 하는 시점에 필드에 인스턴스를 넣어주는 방식이다. 하지만 해당 코드는 스레드 세이프를 보장하기 위해 synchronized를 사용하여 동기화를 처리하는 과정이 들어가 성능상의 이슈가 있을 수 있다.

두번째 코드를 보자

//지연 초기화
public class SingleEx3 {
    private static SingleEx3 singleEx;

    private int val = 3;

    private SingleEx3() {
        System.out.println("3 == SingleEx3 클래스 로딩");
    }

    public static SingleEx3 getSingleEx3() {
        System.out.println("1 == getSingleEx3 메소드 호출 ! ! !");
        return SingleEx3.InnerInstanceClass.singleEx3;
    }

    private static class InnerInstanceClass {
        static {
            System.out.println("2 == Inner 초기화 ! ! !");
        }
        private static final SingleEx3 singleEx3 = new SingleEx3();

        private InnerInstanceClass() {}
    }

    public int getVal() {
        return val;
    }

    public void setVal(int val) {
        this.val = val;
    }

}

위 코드는 클래스 내에 InnerInstanceClass를 만들어 getSingleEx3 메소드를 최초 호출 시에 Inner 클래스가 초기화되고 singleEx3라는 필드 값을 반환하여 스레드 세이프와 지연 초기화까지 가능하게 하는 코드이다.

번외

번외로 자바에서도 싱글톤 방식으로 제공하는 클래스가 있다. 바로 Runtime 객체이다 해당 객체를 new를 통해 생성하려고 하면 에러가 날것이다.

 

그래서 new 연산자가 아닌 아래와 같이 getRuntime 메소드를 통해 Runtime객체를 얻을(?) 수 있다.

 

Runtime runtime = Runtime.getRuntime();

 

참고 : https://jdm.kr/blog/10

'개발 > 그냥 코딩' 카테고리의 다른 글

이진수 출력(재귀)  (0) 2023.08.06
(알고리즘)격자판 최대합  (0) 2023.04.10