[Java] 싱글톤을 보장하는 방법

naneun·2022년 2월 27일
0

Java

목록 보기
5/7
post-thumbnail

클래스 레벨의 동시성

싱글톤을 보장 하는 방법

public class Singleton {
    private static Singleton singleton;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (singleton == null) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            singleton = new Singleton();
        }
        return singleton;
    }
}
  • getInstance() 메서드는 싱글톤 패턴을 보장하지 못한다.
Thread t1 = new Thread(() -> {
    Singleton singleton = Singleton.getInstance();
    System.out.println(singleton);
});
Thread t2 = new Thread(() -> {
    Singleton singleton = Singleton.getInstance();
    System.out.println(singleton);
});
  • singleton 객체가 null 일 때 여러 스레드에서 해당 블록에 진입할 수 있기 때문

  • 동시성을 클레스 레벨로 적용하여 해결
public static synchronized Singleton getInstance() {
    if (singleton == null) {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        singleton = new Singleton();
    }
    return singleton;
}
  • 같은 객체를 참조하는 것을 확인할 수 있다

  • 객체 레벨의 동시성은 적용할 수 없다!

public static Singleton getInstance() {
    synchronized (singleton) {
        if (singleton == null) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            singleton = new Singleton();
        } 
    }
    return singleton;
}

  • 최초에는 락을 걸고 점유할 객체가 존재하지 않기 때문이다.
public static Singleton getInstance() {
    synchronized (Singleton.class) {
        if (singleton == null) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        singleton = new Singleton();
        }
    }
    return singleton;
}
  • 이렇게 클래스 레벨 동시성 블럭을 사용해서 해결할 수도 있다
profile
riako

0개의 댓글