[Singleton 패턴] 기억력 저하로 인한 복습...

ITWeb/개발일반 2015. 11. 17. 16:15

아는 것도 자주 사용하지 않거나 보지 않으면 잊혀지기 마련 입니다.

그래서 이런 간단한 것도 기억하기 위해 글 남겨 봅니다.


한빛미디어)

http://www.hanbit.co.kr/network/view.html?bi_id=466


위키피디아)

https://en.wikipedia.org/wiki/Singleton_pattern


소프트웨어 디자인 패턴에서 싱글턴 패턴(Singleton pattern)을 따르는 클래스는, 생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴한다. 이와 같은 디자인 유형을 싱글턴 패턴이라고 한다.


구현 예제 코드는 위 링크에 자세하게 나와 있습니다.

그러나 복습 하는 차원에서 타이핑 해보겠습니다. ^^;


[Lazy Initialization]

public class SingletonDemo {

    private static volatile SingletonDemo instance;

    private SingletonDemo() { }


    public static SingletonDemo getInstance() {

        if (instance == null ) {

            synchronized (SingletonDemo.class) {

                if (instance == null) {

                    instance = new SingletonDemo();

                }

            }

        }


        return instance;

    }

}

▶ 위 코드에서는 DCL (Double Checked Lock) 기법이 적용된 예제 입니다. 쓰레드 경합 시 instance 가 생성 되지 전에 딱 한번만 locking 하도록 한다는 뭐 그런 이야기 입니다.


public class SingletonDemo {

    private static volatile SingletonDemo instance = null;

    private SingletonDemo() { }


    public static synchronized SingletonDemo getInstance() {

        if (instance == null) {

            instance = new SingletonDemo();

        }


        return instance;

    }

}

▶ 위 코드는 상대적으로 쓰레드 경합이 적은 환경에서 사용하도록 간결하게 작성된 예제 입니다.


[Eagar Initialization]

public class Singleton {

    private static final Singleton INSTANCE = new Singleton();


    private Singleton() {}


    public static Singleton getInstance() {

        return INSTANCE;

    }

}

▶ 일반적으로 간결하게 사용할 수 있는 코드 예제입니다. 하지만 instance 가 생성된 후에라야 쓰레드에서 단일 인스턴스를 사용할 수가 있게 됩니다.


[Static Block Initialization]

public class Singleton {

    private static final Singleton instance;


    static {

        try {

            instance = new Singleton();

        } catch (Exception e) {

            throw new RuntimeException("Darn, an error occurred!", e);

        }

    }


    public static Singleton getInstance() {

        return instance;

    }


    private Singleton() {

        // ...

    }

}

▶ static 블럭으로 구현한 코드 예제 입니다.


[Initialization-on-demand holder idiom]

public class Singleton {

        // Private constructor. Prevents instantiation from other classes.

        private Singleton() { }


        /**

         * Initializes singleton.

         *

         * {@link SingletonHolder} is loaded on the first execution of {@link Singleton#get

Instance()} or the first access to

         * {@link SingletonHolder#INSTANCE}, not before.

         */

        private static class SingletonHolder {

                private static final Singleton INSTANCE = new Singleton();

        }


        public static Singleton getInstance() {

                return SingletonHolder.INSTANCE;

        }

}

▶ 이 방법은 DCL 기법을 java의 메모리 모델로 변형한 예제 이고, 별도의 처리 없이 thread safe 하게 이용할 수 있습니다.


[The enum way]

public enum Singleton {

    INSTANCE;

    public void execute (String arg) {

        // Perform operation here

    }

}

▶ 위 코드 예제는 singleton 구현중 제일 우수한 코드라고 합니다.

: