2021.11.14_02.멀티쓰레드환경에서안전하게구현하는방법
본문 바로가기
CS Study/디자인패턴

2021.11.14_02.멀티쓰레드환경에서안전하게구현하는방법

by KyeongMin 2021. 11. 14.
728x90
반응형

싱글톤패턴 구현하는 방법 1

  • 이전 방법은 멀티에 최적화 되지 않음
  • 멀티의 환경에서 두개가 new를 실행하면 달라지니까 싱글톤이 아니게됨

동기화 시키기

public class Settings{

    private static Settings instance;
    
    private Settings(){}
    
    public static synchronized Settings getInstance(){
		if(instance == null){
            instance = new Settings();
        }
        return instance ;
    }
}
  • 동시에 못들어가게하니까 가능
  • 하지만 동기화 처리 작업 때문에 성능에 불이득이 생기는 단점이 생김
  • 락을 걸어서 하기 때문에 그 쓰레드만 들어가고 해제하고 다른 쓰레드 처리하니까 성능 부하 생김
  • 안전하지만 성능이 중요하다면 좋지 않음
  • 객체 생성 비용이 비싸지 않는다면 미리 만들어서 해됨

이른 초기화 (eager initialization)사용

  • public class Settings{
    
        private static final Settings INSTANCE = new Settings();
        
        private Settings(){}
        
        public static Settings getInstance(){
    		return INSTANCE;
        }
    }
  • c#은 대문자로 해도 상관 없음
  • 자바는 규약이 소문자로 시작함
  • 이방법 쓰레드 세이프하다.
  • 멀티 쓰레드에서도 안전하다 하지만 미리 만든다는 자체가 단점이 될 수 있음
    • 이것이 메모리 과정이 길고 그렇다고 할때 쓰지않으면 오랜 시간 걸린것 치고 안쓰면 좋지 않으니
    • 이것을 사용 할때만 만들고 싶다면 어떻게 해야할까?

doble checked locking 사용하기

public class Settings{

    private static volatile Settings instance;
    
    private Settings(){}
    
    public static synchronized Settings getInstance(){
		if(instance == null){
            synchronized (Settings.class){
                if(instance = null){
                   instance = new Settings();
                }
            }
        }
        return instance ;
    }
}
  • 체크를두번해서 이름이 이렇다.
  • 동기화 블록으로 다른 쓰레드 접근을 못함
  • 이경우는 volatile 을 선언해야함
  • 왜 더 효율적인가하면 매번 getInstance 실행한다고 하더라도 매번 동기화 실행하는것 아니기때문이고
    • 매번 빈번하게 멀티쓰레드로 동작하면 그때만 동작하기 때문에 좀더 성능에 유리함
    • 또다른 장점은 인스턴스가 필요한 시점에서만 만들 수 있음
  • 우선 이 자체는 복잡함 그리고 왜 volatile를 쓰는 이유도 알아야하고 1.5버전부터 동작하는데
    • 복잡한게 싫다면 다른 방법이 있음

가장 권장하는 방법

  • static inner 클래스 사용하기
public class Settings{
    
    private Settings(){}
    
    private static class SettingsHolder{
		private static final Settings INSTANCE = new Settings();
    }
    
    public static synchronized Settings getInstance(){
        return SettingsHolder.INSTNACE ;
    }
}
  • 레이지 로딩도 가능하다.

https://github.com/3DPIT/study/blob/master/05.%EC%BD%94%EB%94%A9%EC%9C%BC%EB%A1%9C%ED%95%99%EC%8A%B5%ED%95%98%EB%8A%94GoF%EC%9D%98%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4/01.%EA%B0%9D%EC%B2%B4%EC%83%9D%EC%84%B1%EA%B4%80%EB%A0%A8%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4/2021/11/1114/01.%EC%8B%B1%EA%B8%80%ED%86%A4%ED%8C%A8%ED%84%B4/02.%EB%A9%80%ED%8B%B0%EC%93%B0%EB%A0%88%EB%93%9C%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C%EC%95%88%EC%A0%84%ED%95%98%EA%B2%8C%EA%B5%AC%ED%98%84%ED%95%98%EB%8A%94%EB%B0%A9%EB%B2%95/2021%EB%85%8411%EC%9B%9414%EC%9D%BC_%EB%A9%80%ED%8B%B0%EC%93%B0%EB%A0%88%EB%93%9C%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C%EC%95%88%EC%A0%84%ED%95%98%EA%B2%8C%EA%B5%AC%ED%98%84%ED%95%98%EB%8A%94%EB%B0%A9%EB%B2%95.md#%EC%8B%B1%EA%B8%80%ED%86%A4%ED%8C%A8%ED%84%B4-%EA%B5%AC%ED%98%84%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95-1

 

GitHub - 3DPIT/study

Contribute to 3DPIT/study development by creating an account on GitHub.

github.com

 

728x90
반응형

댓글