싱글톤(Singleton)패턴에 대하여

보람찬하루·2023년 10월 22일
0

design-pattern

목록 보기
2/2
  • 싱글톤패턴이란 ?

    sw디자인 패턴에서 싱글턴 패턴을 따르는 클래스는 생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴

    = 객체의 인스턴스를 한개만 생성되게 하는 패턴
    package kail.study.java.design.single;
        
        public class Printer {
        	private static Printer printer = null;
        
        	private Printer(){}
        
        	public static Printer getInstance() {
        		if(printer == null) {
        			printer = new Printer();
        		}
        		return printer;
        	}
        
        	public void print(String input) {
        		System.out.println(input);
        	}
        }


  • 사용하는 상황
    1. 프로그램 내 하나의 객체만 존재해야 할 때
    2. 프로그램 내 여러 부분에서 해당 객체를 공유하며 사용해야할 때


  • 사용 이유
    1. 메모리 측면
      : 한개의 인스턴스만 고정 메모리 영역에 생성하고 추후 해당 객체에 접근할 때 메모리 낭비 방지 가능
    2. 속도 측면
      : 이미 생성된 인스턴스 활용 시 속도 측면에 이점
    3. 데이터 공유 측면
      : 전역 사용 인스턴스이기 때문에 다른 여러 클래스에서 데이터를 공유


  • 사용의 문제점
    1. Multi-Thread 환경에서 안전성 문제 발생

      여러 쓰레드가 공유되고 있는상황에서 조건문이 동시에 두번 돌 수 있는데 이때 하나의 인스턴스가 아닌 여러개의 인스턴스 발생가능

      public static Printer getInstance() {
          		if(printer == null) {
          			printer = new Printer();
          		}
          		return printer;
          	}
    2. 서로 다른 프로세스에서 처리할 경우 값의 일관성에 문제 발생

      public class Printer {
          	private static Printer printer = null;
          	private int count = 0;
          
          	private Printer(){}
          
          	public static Printer getInstance() {
          		if(printer == null) {
          			printer = new Printer();
          		}
          		return printer;
          	}
          
          	public void print(String input) {
          		count++;
          		System.out.println(input + "count : "+ count);
          	}
          }


  • 해결방법
    1. 정적 변수에 인스턴스를 만들어 바로 초기화 하는 방법

      : 정적 변수는 객체가 생성되기 전(= 클래스가 메모리에에 로딩할 때) 만들어져 초기화가 한번만 실행되며 프로그램 종료시까지 없어지지않기 때문에 클래스에서 생성된 모든 객체에서 참조 가능

      • 이방법으로도 완벽히 해결이 되지 않기 때문에 synchronized 키워드 사용해서 여러 스레드에서 동시 접근을 막는다
        package kail.study.java.design.single;
            
            public class Printer {
            	private static Printer printer = new Printer();
            	private static int count = 0;
            
            	private Printer(){}
            
            	public static Printer getInstance() {
            		return printer;
            	}
            
            	public synchronized static void print(String input) {
            		count++;
            		System.out.println(input + "count : "+ count);
            	}
            }


  1. 인스턴스를 만드는 메서드에 동기화하는 방법 : 인터페이스의 경우 정적 메서드를 가질 수 없어서 정적 클래스를 사용할 수 없다


  • 결론
    • 멀티 쓰레드 환경 에서의 싱글톤
      • Synchronized를 통해 관리하면 되며 다양한 변화에 대응하기 위해 인터페이스의 형태로 관리하면 좋다.
    • 단일쓰레드환경에서 싱글톤
      • 정적 클래스의 형태로 사용하면 된다. (클래스 로딩단계에서 바로 초기화 되도록)
      • 물론 이 경우에서도 테스트를 위한 모의객체를 만들고 혹은 다른 목적으로 사용한다면 멀티쓰레드 환경에서 싱글톤을 사용하듯이 사용하면 된다.




profile
를 만들어 가자

0개의 댓글