본문으로 바로가기

 

싱글톤 패턴 Singleton Pattern

 

 

1. 개념

싱글톤 패턴 (Singleton Pattern) 이란 인스턴스를 1개만 생성하는 디자인 패턴이다.

보통은 객체가 사용되는 시점마다 new 를 이용하여 인스턴스를 매번 생성하여 사용하지만,싱글톤 패턴은 오직 하나의 인스턴스를 메모리에 등록하여 동시에 여러 스레드가 공유하여 사용하는 방식을 채택한다. (이 때문에 반드시 Thread-safe가 보장되어야 함)

 

2.  싱글톤 패턴 - 가장 심플한 버전

# Eager Initialization # 이른 초기화 # Thread-safe

 

이른 초기화 싱글톤 패턴의 핵심은 다음과 같다.

 

(1) create an object of SingleObject

- 클래스 멤버로 인스턴스 생성 (이후 여러 스레드에서 공유되어 사용될 인스턴스. static으로 정의되어야 함)

- static 은 정적 바인딩되기 때문에 클래스 로더가 초기화되는 시점 (컴파일단계) 에서 인스턴스가 메모리에 등록됨.

-> 따라서 Thread-safe 보장!

 

(2) make the PRIVATE contructor

- 반드시 private 생성자를 정의할 것 (외부에서 아무나 생성자를 호출해서 인스턴스를 생성해서는 안 됨)

 

(3) get the ONLY object available

- 인스턴스를 반환하는 메소드 생성 (static으로 정의되어야 함)

 

🔻SingleObject.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class SingleObject {
 
   // (1) create an object of SingleObject
   private static SingleObject instance = new SingleObject();
 
   // (2) make the constructor private so that this class cannot be
   //instantiated
   private SingleObject(){}
 
   // (3) Get the only object available
   public static SingleObject getInstance(){
      return instance;
   }
 
   public void showMessage(){
      System.out.println("Hello World!");
   }
}
cs

 

🔻 SingletonParrernDemo.java

1
2
3
4
5
6
7
8
9
10
public class SingletonPatternDemo {
   public static void main(String[] args) {
 
      //Get the only object available
      SingleObject object = SingleObject.getInstance();
 
      //show the message
      object.showMessage();
   }
}
cs

Demo 클래스에서는 SingleObject의 getInstance 메소드를 통해 단일 인스턴스를 받아올 수 있다.

 

❗이때, SingleObject object = new SingleObject() 로 인스턴스를 생성하면 The constructor SingleObject() is not visible 라는 컴파일에러가 발생한다. 애초에 외부에서 임의로 인스턴스생성하는것을 막기 위해 생성자를 private으로 정의했기 때문이다.

 

3. 싱글톤 패턴 - 개선된 버전

# Lazy Initialization # 동기화 블럭 # Thread-safe

 

앞서 제시된 심플한 버전의 싱글톤 패턴은 몇 가지 문제가 존재한다.

1. Exception handling 불가능

2. 인스턴스가 필요하지 않을 때에도 무조건 생성 -> resource wastage

 

이 문제점을 개선한 것이 다음 Lazy Initilization 버전의 싱글톤 패턴이다.

 

(1) synchronized method

- Exception handling을 하기 위해 static method 내부에서 객체가 생성되도록 한다.

- 이때, Thread-safe 하지 않기 때문에 synchronized 로 쓰레드의 동시접근을 막는다. (Method 단의 동시성 제어)

 

(2) instance가 null일 경우에만 생성하여 자원낭비를 막는다.

 

(3) volatile 키워드를 사용.

- 원래의 MultiThread 어플리케이션에서는 Task를 수행하는 동안 성능 향상을 위해 Main Memory에서 읽은 변수 값을 CPU Cache에 저장하게 된다. 만약에 Multi Thread환경에서 Thread가 변수 값을 읽어올 때 각각의 CPU Cache에 저장된 값이 다르기 때문에 변수 값 불일치 문제가 발생하게 될 수 있다.

- 따라서 volatile 키워드를 사용하여 변수의 값을 Read할 때마다 CPU cache에 저장된 값이 아닌 Main Memory에서 읽도록 명시한다.

 

🔻 Lazysingleton.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class LazySingleton
{
 
  private volatile static LazySingleton instance;
 
  private LazySingleton(){}
 
  public static LazySingleton getInstance() {
    if (instance == null)
    {
      //synchronized block to remove overhead
      synchronized (LazySingleton.class)
      {
        if(instance==null)
        {
          instance = new LazySingleton();
        }
       
      }
    }
    return instance;
  }
}
cs

 

❗ 이 경우 기능적으로는 잘 동작하지만 성능저하가 발생할 수 있다.

instance를 생성할때만 동시접근을 막으면 되는데 method전체를 synchronized 처리를 해버려서 인스턴스호출 자체도 막히게 된다.

 

💡 그래서 대신 synchronized block 을 사용한다!

- method 전체가 아니라 instance 생성하는 부분만 synchronized block처리를 하면 return되는 부분은 자유로워진다.

 

🔻 Lazysingleton.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class LazySingleton
{
 
  private volatile static LazySingleton instance;
 
  private LazySingleton(){}
 
  public static LazySingleton getInstance() {
    if (instance == null)
    {
      //synchronized block to remove overhead
      synchronized (LazySingleton.class)
      {
        if(instance==null)
        {
          instance = new LazySingleton();
        }
       
      }
    }
    return instance;
  }
}
cs

 

3. 싱글톤 패턴 - 가장 많이 사용되는 버전

# Lazy Holder # 게으른 홀더 # Thread-safe

 

 


참고자료

 

https://www.tutorialspoint.com/design_pattern/singleton_pattern.htm

 

Design Pattern - Singleton Pattern - Tutorialspoint

Design Pattern - Singleton Pattern Singleton pattern is one of the simplest design patterns in Java. This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object. This pattern involves a singl

www.tutorialspoint.com

https://www.geeksforgeeks.org/java-singleton-design-pattern-practices-examples/

 

Java Singleton Design Pattern Practices with Examples - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

https://nesoy.github.io/articles/2018-06/Java-volatile

 

Java volatile이란?

 

nesoy.github.io

 

반응형