3. Singleton 단일 모드

3556 단어

1. 정의


어떤 종류가 하나의 실례만 있을 뿐만 아니라, 자체적으로 실례화하여 전체 시스템에 이 실례를 제공하도록 확보하다

2. 특징

  • 단일 예류는 하나의 실례만 있을 수 있다.
  • 단일 예류는 반드시 스스로 자신의 유일한 실례를 만들어야 한다.
  • 단례류는 모든 다른 대상에게 이 실례를 제공해야 한다.

  • 3. 단일 모델은 게으름뱅이와 굶주림식으로 나눌 수 있다

  • 게으름뱅이 단일 모드: 클래스를 불러올 때 초기화하지 않습니다.
  • 굶주린 일례 모드: 클래스를 불러올 때 초기화가 완료되어 클래스를 불러오는 것은 비교적 느리지만 대상을 얻는 속도가 빠르다.

  • 1) 게으름뱅이식, 노정이 안전하지 않다
    이런 방식은 가장 기본적인 실현 방식이다. 이런 실현의 가장 큰 문제는 다선정을 지원하지 않는 것이다.synchronized를 잠그지 않았기 때문에 엄격한 의미에서 이것은 단일 모드가 아니다.
    public class SingletonDemo1 {
        private static SingletonDemo1 instance;
        private SingletonDemo1(){}
        public static SingletonDemo1 getInstance(){
            if (instance == null) {
                instance = new SingletonDemo1();
            }
            return instance;
        }
    }
    

    2) 게으름뱅이식, 라인 안전
  • 장점: 첫 번째 호출이 초기화되어 메모리 낭비를 피한다.
  • 단점:synchronized를 잠궈야만 단례를 보장할 수 있지만 잠그는 것은 효율에 영향을 줄 수 있다.
  • public class SingletonDemo2 {
        private static SingletonDemo2 instance;
        private SingletonDemo2(){}
        public static synchronized SingletonDemo2 getInstance(){
            if (instance == null) {
                instance = new SingletonDemo2();
            }
            return instance;
        }
    }
    

    3) 아사자식
    classloder 메커니즘을 바탕으로 여러 라인의 동기화 문제를 피했지만, instance는 클래스를 불러올 때 실례화되었고, 이때 instance를 초기화하는 것은lazy loading 효과에 이르지 못했다.
  • 장점: 잠금이 없으면 집행 효율이 높아진다.
  • 단점: 클래스를 불러올 때 초기화하고 메모리를 낭비합니다.
  • public class SingletonDemo3 {
        private static SingletonDemo3 instance = new SingletonDemo3();
        private SingletonDemo3(){}
        public static SingletonDemo3 getInstance(){
            return instance;
        }
    }
    

    4) 아사자, 변종
    클래스 초기화 즉 실례화 instance
    public class SingletonDemo4 {
        private static SingletonDemo4 instance = null;
        static{
            instance = new SingletonDemo4();
        }
        private SingletonDemo4(){}
        public static SingletonDemo4 getInstance(){
            return instance;
        }
    }
    

    5) 등록식/정적 내부 클래스
    이런 방식은 쌍검쇄 방식과 같은 효능을 얻을 수 있지만 실현은 더욱 간단하다.정적 영역에 대해 지연 초기화를 사용하려면 이중 잠금 방식이 아니라 이런 방식을 사용해야 한다.이런 방식은 정적 영역의 경우에만 적용되며, 이중 잠금 방식은 실례 영역이 초기화를 지연할 때 사용할 수 있다.
  • classloder의 메커니즘을 이용하여 instance를 초기화할 때 하나의 라인만 있음을 보장합니다.
  • 이런 방식은singleton Demo 5종류가 불러왔는데 instance가 반드시 초기화되는 것은 아니다.SingletonHolder 클래스가 주동적으로 사용되지 않았기 때문에 getInstance 방법을 호출할 때만 SingletonHolder 클래스를 불러오는 것을 표시하여 instance를 실례화합니다.
  • public class SingletonDemo5 {
        private static class SingletonHolder{
            private static final SingletonDemo5 instance = new SingletonDemo5();
        }
        private SingletonDemo5(){}
        public static final SingletonDemo5 getInsatance(){
            return SingletonHolder.instance;
        }
    }
    

    6) 열거
    자동적으로 서열화 메커니즘을 지원하여 여러 차례의 실례화를 절대 방지한다.
    public enum SingletonDemo6 {
        instance;
        public void whateverMethod(){
        }
    }
    

    7) 이중 잠금/이중 잠금(DCL, 즉 Double-checked locking)
    이런 방식은 이중 잠금 메커니즘을 채택하여 안전하고 다선정 상황에서 고성능을 유지할 수 있다
    public class SingletonDemo7 {
        private volatile static SingletonDemo7 singletonDemo7;
        private SingletonDemo7(){}
        public static SingletonDemo7 getSingletonDemo7(){
            if (singletonDemo7 == null) {
                synchronized (SingletonDemo7.class) {
                    if (singletonDemo7 == null) {
                        singletonDemo7 = new SingletonDemo7();
                    }
                }
            }
            return singletonDemo7;
        }
    }
    

    좋은 웹페이지 즐겨찾기