본문 바로가기

웹개발/JAVA

싱글톤 클래스

싱글톤 클래스란?

  • 오직 하나의 인스턴스 생성
    • 이 하나의 인스턴스(this single object or instance) 를 통해서 다른 클래스들에서 접근을 할 수 있다.

 

싱글톤 클래스의 목적

  • 객체 생성의 수를 오직 하나로 제한하기 위함
    • => 자원에 대한 접근 제한을 보장한다. ex) 소켓, 데이터베이스 연결
  • 메모리 공간 낭비를 막을 수 있다. 

 

싱글톤 클래스 만드는 법

  1. private 키워드로 싱글톤 클래스의 생성자를 선언한다.
    • private => 다른 클래스에서 인스턴스 생성 막기 위해
  2. 싱글톤 클래스의 객체를 리턴하는 static 메소드를 선언한다. 

 

일반 클래스 vs. 싱글톤 클래스

  • 일반 클래스 
    • 인스턴스를 만들기 위해 자바 생성자를 이용한다. 
  • 싱글톤 클래스
    • 싱글톤 클래스의 인스턴스를 만들기 위해 getInstance() method 를 이용한다. 

 

다양한 싱글톤 클래스의 디자인 형태들

  1. Eager Initialization Method
    • 가장 기본적이고 단순한 기술
    • 클래스의 인스턴스가 JVM이 객체에 대한 메모리를 만들 때 생성된다. 
    • 프로그램이 언제나 이 싱글톤 클래스의 객체나 인스턴스를 사용할 때 이 방법을 사용한다.
    • public class EagerInitialization
      {
        //Instance will be created at load time
        private static EagerInitialization obj = new EarlyInitialization();
        public String string;
        //Creating private constructor
        private EagerInitialization()
        {
          string = "Welcome to TechVidvan's Tutorial of Java";
        }
        //Declaring static method
        public static EagerInitialization getInstance()
        {
          return obj;
        }
        public static void main(String args[])
        {
          EagerInitialization text = EagerInitialization.getInstance();
          //original string
          System.out.println("Original String:");
          System.out.println(text.string);
          //text in upper case
          System.out.println("String in Upper Case:");
          text.string = (text.string).toUpperCase();
          System.out.println(text.string);
          }
       }
      - 단점 : 객체가 이용이 안 될 때는 불필요한 객체의 생성으로 자원 낭비와 CPU 시간 낭비로 이어진다. 
  2. Lazy Initialization Method
    • Eager Initialization method 의 단점을 보완할 수 있는 방법
    • Lazy 게으르게 initialize를 한다.  => 클래스의 인스턴스 생성을 필요해질 때까지 지연시킨다. 
    • public class LazyInitialization
      {
        // private instance, so that it can be
        // accessed by only by getInstance() method
        private static LazyInitialization instance;
        public String string;
        private LazyInitialization ()
        {
          // private constructor
          string = "Welcome to TechVidvan's Tutorial of Java";
        }
        //method to return instance of class
        public static LazyInitialization getInstance()
        {
          if (instance == null) // 인스턴스가 필요할 때까지 인스턴스 생성을 지연시킴
          {
            // if instance is null, initialize
            instance = new LazyInitialization ();
          }
          return instance;
        }
        public static void main(String args[])
        {
          LazyInitialization text = LazyInitialization .getInstance();
          //original string
          System.out.println("The String is:");
          System.out.println(text.string);
        }
      }
  3. Thread Safe Singleton Method
    • 멀티 쓰레드 환경에서도 싱글톤 클래스를 만들 수 있음
      • getInstance() 메소드에 'synchronized' 키워드를 추가한다.
      • 'synchronized' 키워드 추가는 멀티쓰레드의 동시 접속을 막는다.  -  Thread Safe
    • public class ThreadSafeSingleton
      {
        //Thread Safe Singleton
      
        private static ThreadSafeSingleton instance;
        private ThreadSafeSingleton()
        {
          // private constructor
        }
        //Making the getInstance method as synchronized(동기)
        public static synchronized ThreadSafeSingleton getInstance()
        {
          if(instance == null)
          {
            instance = new ThreadSafeSingleton();
          }
          return instance;
        }
      }
      -> 단점 : 오버헤드가 고려된다.
  4. Lazy Initialization with Double Lock Method
    • Thread Safe Singleton Method 와 같이 method 자체에 synchronized  를 하면 오버헤드 문제가 생기므로 이를 해결하기 위해 처음 initialize 할 때 블록만 동기화(synchronized)를 해서 쓰레드들이 최소한으로 기다리도록 하낟.
    • public class LazyDoubleLock
      {
              // Java code to explain double-check locking private instance so that it can be
              // accessed by only by getInstance() method
              private static LazyDoubleLock instance;
              public String string;
      
              private LazyDoubleLock()
              {
                      // private constructor
                      string = "Welcome to TechVidvan's Java Tutorial";
              }
              public static LazyDoubleLock getInstance()
              {
                      if (instance == null)
                      {
                              //synchronized block to remove overhead
                              synchronized (LazyDoubleLock.class)
                              {
                                      if(instance==null)
                                      {
                                              // if instance is null, initialize
                                              instance = new LazyDoubleLock();
                                      }
                              }
                      }
                      return instance;
              }
              public static void main(String args[ ])
              {
                      LazyDoubleLock text = LazyDoubleLock.getInstance();
                      //original string
                      System.out.println("Original String:");
                      System.out.println(text.string);
      
                      //text in upper case
                      System.out.println("String in Upper Case:");
                      text.string = (text.string).toUpperCase();
                      System.out.println(text.string);
      
              }
      }
      -> 단점 : 첫번째로 instance 가 생성될 때의 성능에 영향을 미친다.
  5. Lazy Load Method
    • JVM static data 필드들을 그 필드들이 필요로 될 때 처리한다. 
    • public class LazyLoadMethod
      {
        //Lazy Load Method
        private LazyLoadMethod()
        {
      
        }
        private static class SingletonClassHolder
        {
          private static LazyLoadMethod instance= new LazyLoadMethod();
        }
        public static LazyLoadMethod getInstance()
        {
          return SingletonClassHolder.instance;
        }
      }
  6. Static Block Initialization Method
    • Eager Initialiation method에서 객체 생성중 예외를 처리할 때\
  7. Bill Pugh Implementation Method

 

 

 

 

참고 : https://techvidvan.com/tutorials/java-singleton-class/

'웹개발 > JAVA' 카테고리의 다른 글

Serializable(직렬화), 도메인 객체에 implements Serializable  (0) 2022.02.15
Java EE vs. Java SE  (0) 2021.10.31
[JAVA] I/O Stream  (0) 2021.09.08
[JAVA] Comparator<>, Comparable<>  (0) 2021.09.04
[JAVA] MAP - HashMap, TreeMap  (0) 2021.09.04