001 단일 모드 | 5가지 구현 방법

4115 단어

굶주린 사람

public class Singleton {
    private static Singleton instance = new Singleton();
    private Singleton() { }
    public static Singleton getInstance() {
        return instance; 
    }
}

사유화 구조 함수로 내부 정적 대상을 만들고 정적 방법으로 되돌려줍니다.혹은 다음과 같은 효과
public class Singleton {
    private static Singleton instance = null;
    static {
        instance = new Singleton();
    }
    private Singleton() { }
    public static Singleton getInstance() {
        return this.instance; 
    }
}

단점, 수요에 따라 대상을 만들지 않아 자원 낭비를 초래한다

게으름뱅이


필요에 따라 글로벌 고유 객체 생성
public class Singleton {
    private static Singleton instance = null;
    private Singleton() { }
    public static Synchronized Singleton getInstance() {
          if (instance == null) {
                instance = new Singleton();
          }
        return instance;
    }
}

단점, Synchronized는 매번 방문할 때마다 자물쇠를 잠그고 풀어야 하는데 실제 대상은 이미 있는데 왜 이렇게 하느냐는 자원 낭비다.

이중 검사


게으름뱅이의 변종은 성능을 향상시키고 수요에 따라 대상을 생성하며 후속에는 자물쇠를 채울 필요가 없다.
public class Singleton {
    private static Singleton instance = null;
    private Singleton() { }
    public static Singleton getInstance() {
        if (instance == null) { // , 
            synchronized(Singleton.class) { // ,
                if (instance == null) { // , 
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

이상의 코드는 성능을 향상시키지만 명령 리셋 문제가 발생할 수 있다. 명령 리셋은 JVM이 코드를 최적화하는 과정이고 최종 결과에 영향을 주지 않을 때 명령 집행 순서를 조정한다. 그러면 이중 검사가 효력을 상실하고 개선될 수 있다volatile
public class Singleton {
    private static volatile Singleton instance = null;
    private Singleton() { }
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized(Singleton.class) {
                if (instance == null){
                    instance = new Singleton();
                }
            }
        }
       return instance; 
    }
}

정적 내부 클래스

public class StaticSingleton {
    private StaticSingleton() {}
    private static class SingletonHolder {
        private static StaticSingleton INSTANCE = new StaticSingleton();
    }
    
    public static StaticSingleton  getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

매거


상술한 방법은 사유화 구조 함수를 통해 단열을 실현할 수 있으나 반사 메커니즘을 통해 새로운 대상을 강제로 구성할 수 있다StaticSingleton tmp=(StaticSingleton)Class.forName("com.xx.StaticSingleton").newInstance();따라서 매거를 사용하면 이것을 피할 수 있다
  • 매거된 구조 함수는 반드시 사유
  • 이어야 한다.
  • 매거 중의 속성은 반드시 맨 앞에 놓아야 한다. 보통 대문자
  • 매거진에서 방법을 정의할 수 있고 속성은 다시 쓸 수 있는 방법, 인용 방법
  • public enum TrafficLamp {
        RED(30) {
             // 
            public TrafficLamp nextLamp() {
                return GREEN;
            }
        },
        GREEN(20) {
            public TrafficLamp nextLamp() {
                return YELLOW;
            }
        },
        YELLOW(10) {
            public TrafficLamp nextLamp() {
                return RED;
            }
        };
    
        // 
        public abstract TrafficLamp nextLamp();
    
        private int time;
    
        private TrafficLamp(int time) {
            this.time = time;
        }
    
        public static void main(String[] args) {
            try {
                TrafficLamp tmp=(TrafficLamp)Class.forName("com.roocon.thread.t5.TrafficLamp").newInstance();
            } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
    

    이 안에 있는 RED GREEN YELLOW는 모두 하나의 예입니다. 그리고 매거진을 반사하면 오류가 발생합니다.
    java.lang.InstantiationException: com.roocon.thread.t5.TrafficLamp
        at java.lang.Class.newInstance(Class.java:427)
        at com.roocon.thread.t5.TrafficLamp.main(TrafficLamp.java:30)
    Caused by: java.lang.NoSuchMethodException: com.roocon.thread.t5.TrafficLamp.()
        at java.lang.Class.getConstructor0(Class.java:3082)
        at java.lang.Class.newInstance(Class.java:412)
        ... 1 more
    

    좋은 웹페이지 즐겨찾기