티스토리 뷰

Java

[Java] Singleton

cherishee 2020. 3. 3. 16:46

Singleton


싱글톤이란?

특정 클래스에 대한 인스턴스를 최초 단 한 번만 static 메모리에 할당하고 해당 클래스에 대한 생성자를 여러번 호출하더라도 실제로 생성된 객체는 하나이고 최초에 생성한 객체를 반환하는 디자인 패턴이다. (생성자를 private으로 선언해서 생성을 못하도록 하고 getInstance()로 객체를 받아서 사용한다. ) 즉, 어플리케이션의 특정 클래스에 대한 유일 객체를 보장하는 디자인 패턴이다.

싱글톤 패턴을 사용하는 이유

  • 싱글톤 패턴이 적용된 클래스에 대한 new 연산을 수행하더라도 이미 한 번 할당된 메모리 영역의 인스턴스를 사용하기 때문에 메모리 낭비를 방지할 수 있다.
  • Static 객체이기 때문에 다른 클래스의 객체들이 데이터를 공유하기 쉽다.
  • 한 번 객체를 생성하면 그 이후로 부터는 생성된 객체를 사용하기 때문에 객체 로딩하는 시간이 줄어들어 성능이 좋아진다.

싱글톤 패턴의 문제점

  • 싱글톤 객체가 너무 많은 일을 하거나 데이터를 공유시키는 경우 객체들간의 결합도가 높아져 개방-폐쇄 원칙(객체 지향 설계 원칙)을 위배하게 된다.
  • 멀티쓰레드 환경에서 동기화 처리를 하지 않으면 객체가 두 개 생성되는 등의 문제가 발생한다.

싱글톤 패턴의 구현

  • Static block

    static block을 사용하면 클래스가 로딩될 때 한 번만 실행을 하게 되는 특성을 사용한다. 하지만 객체가 사용되는 시점이 아닌 클래스가 로딩되는 시점에 실행된다는 단점이 있다.

    public class ExClass {
        //Instance
        private static ExClass instance;
    
        //private construct
        private ExClass() {}
    
        static {
            try { instance = new ExClass();}
            catch(Exception e) { throw new RuntimeException("Create instace fail. error msg = " + e.getMessage() ); }
        }
    
        public static ExClass getInstance() {
            return instance;
        }
    }
  • Lazy init

    멀티 쓰레드 환경에서 동시에 getInstance() 메소드를 호출하게 되면 객체가 두 번생성되는 문제가 발생한다.

    public class ExClass {
        //Instance
        private static ExClass instance;
    
        //private construct
        private ExClass() {}
    
        public static ExClass getInstance() {
            if (instance == null) { instance = new ExClass();}
            return instance;
        }
    }
  • Thread safe + lazy

    synchronized를 사용해서 동시 접근을 못하게 막는다. 하지만 성능 저하가 있다.

    public class ExClass {
        //Instance
        private static ExClass instance;
    
        //private construct
        private ExClass() {}
    
        public static synchronized ExClass getInstance() {
            if (instance == null) { instance = new ExClass();}
            return instance;
        }
    }
  • Holder

    자바에서 가장 많이 사용되는 방법이다. JVM의 클래스 로더 메커니즘과 클래스의 로드 시점을 이용하여 내부 클래스를 통해 생성시킴으로써 스레드 간의 동기화 문제를 해결한다.

    public class ExClass {
    
        //private construct
        private ExClass() {}
    
        private static class InnerInstanceClass() {
            private static final ExClass instance = new ExClass();
        }
    
        public static ExClass getInstance() {
            return InnerInstanceClass.instance;
        }
    }

출처

'Java' 카테고리의 다른 글

[Java] char to int  (0) 2020.03.23
[Java] 객체 비교 (Comparator / Comparable)  (0) 2020.03.10
[Java] JVM  (0) 2020.03.03
[Java] Interface  (0) 2020.03.03
[JAVA] String / StringBuffer / StringBuilder  (0) 2020.01.10
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함