본문 바로가기

카테고리 없음

[디자인 패턴] Singleton Pattern

1. 싱글톤 의미

클래스가 하나의 인스턴스만 가질 수 있게 보증한다.


2. 써야할 때

어떤 클래스의 인스턴스 생성 개수의 제어가 필요할 때


3. 사용 예

원도우 매니저

프린터 스풀러


4. 싱글톤 코드1

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
32
33
34
35
36
37
package com.tistory.janggom.base;
 
 
class Singleton{
 
    private static Singleton one;
 
    protected Singleton(){}
 
    public static Singleton getInstance(){        
 
        if(one == null){
            synchronized(Singleton.class){
                if(one == null){
                    //Double Checked Locking
                    one = new Singleton();
                }
            }
        }
 
        return one;
    }
}
 
 
class SingletonEx {
    public static void main(String[] args) {
 
        Singleton s1 = Singleton.getInstance();
        Singleton s2 = Singleton.getInstance();
 
        System.out.println(s1);
        System.out.println(s2);
 
    }
}
 
cs

보통 책에 나오는 기본적인 thread-safe한 싱글톤

생성자를 private를 해서 외부에서의 new 키워드를 막고,

다른 스레드를 막기 위해 더블 체크 사이에 synchronized를 사용했다.


구글링해서 발견한건데 이 코드가 완벽한것처럼 보이는데 

초반에 메모리 할당 시간이랑 인스턴스 생성 시간 차이로 인해 다음 스레드가 null값을 리턴할 경우가 있단다!!!!

정말로 극극극극극극극악의 확률이라서 걍 써도 무방할 듯 하다.


걱정되면 인스턴스 생성후(16) thread.sleep를 아주 조금 주는 방법이 있겠다. 


4. 싱글톤 코드2


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
package com.tistory.janggom.threadsafe;
 
 
class Singleton {
 
      private Singleton() {}
 
      public static Singleton getInstance() {
          return LazyHolder.INSTANCE;
      }
      
      private static class LazyHolder { 
          // 내부 클래스(참조시에만 메모리에 로딩, Lazy Initialization) 
          private static final Singleton INSTANCE = new Singleton(); 
      }
 
    }
 
    class SingletonEx2 {
        public static void main(String[] args) {
 
            Singleton s1 = Singleton.getInstance();
            Singleton s2 = Singleton.getInstance();
 
            System.out.println(s1);
            System.out.println(s2);
 
        }
    }
 
cs

동기화(synchronized)를 사용 안해도 되는 싱글톤

내부 클래스를 사용해서 safe도 보증한다.