2021-06-18 강의록_싱글톤

10170 단어 Java강의록Java

(여기부터 이해하기_클릭)

싱글톤

싱글톤 객체 : 이 클래스로부터 힙 영역에 단 한 번만, 단 하나의 객체만 생성 가능.
힙에 있는 모든 객체가 공유할 용도로 쓰임. 대표적으로 환경설정.
환경설정 정보를 필드로 들고있는 싱글톤 객체가 있다.
이 설정 정보는 하나의 객체에만 있어야 함. 여러 객체에 있으면 내용이 모두 다를 수 있으니까.
단 하나의 객체만 존재해야 하며, 프로그램이 시작되어 종료될 때까지 살아 있어야 함. (=가비지컬렉터GC 작동 X)

가비지 객체
생성되어 아무도 사용하지 않으면 GC가 작동된다.

싱글톤 만드는 방법

  1. 외부에서 new 연산자로 생성자 호출할 수 없도록 막기
    : private 접근제한자를 생성자 앞에 붙임

  2. 클래스 자신의 타입으로 정적 필드 선언
    : 자신의 객체를 생성해 초기화.
    private 접근 제한자 붙여 외부에서 필드 값 변경 불가하도록
    //static 붙이면 clazz 소속이 됨. 한 번 메소드영역에 꽂힌 clazz 객체는 프로그램이 떨어질 때 까지 사라지지 않는다.
    (gc는 힙 영역의 객체에만 해당)

  3. 외부에서 호출할 수 있는 정적 메소드인 getInstance() 선언
    : 정적 필드에서 참조하고 있는 자신의 객체 리턴
    객체를 생성하지 않고 메소드를 호출해야 하므로 static 메소드로 선언!!!!!
    (private으로 막아놨기 때문에 객체생성 X)

//외부에서 역시 접근 불가능하게 private 접근제한자(access modifier) 로 은닉화(캡슐화)
// 단 한 번 생성될 싱글톤 객체의 주소를 보관할 필드 선언		-------------------(2)
private static Singleton singleton = new Singleton();

/////////////////
//모든 쓰레드, 모든 객체에서 공유할 데이터를 보관할 필드를 선언
/////////////////
private int[] intArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};


static {
	log.debug(">>>>>> static initializer invoked.");
		
	Singleton.singleton = new Singleton();
} //static initializer : JVM이 오직 단 한번만 호출되도록 보장하는 블록 
	
//외부에서는 호출 불가능하게 private접근제한자로 은닉화(캡슐화)
private Singleton() {	//외부에서 new연산자로 호출 못하도록 private으로 선언  ---------(1)
	;;
} //default constrctor
	
//외부에서 언제든 호출 가능하도록 하려면, 객체생성 없이도 호출할 수 있도록 static 메소드로 선언	
//싱글톤 객체이 주소를 보관하고 있는 필드의 값을, 언제든 필요로 하는 다른 객체에 줄 수 있도록 
//정적 메소드를 선언						-------------------(3)
static Singleton getInstance() {	
	return singleton;
} //getInstance

배열(intArray)에 왜 static 키워드 붙이지 않는지?
->> 싱글톤은 공유(heap영역의 모든 객체들이 공유)되고, 보호되고 있는 하나의 상자.
이 상자 이미 private static으로 생성되어있고, 이 안에 데이터로서 배열(intArray)을 넣은 것.
Clazz객체로 만드는 의미가 아니다.
메소드 영역은 크기가 크지 않음. 이 안에 큰 배열을 넣는것은 위험하다. (VM 이 죽을 수 있다)
무엇보다 싱글톤객체는 '객체'임.
객체 안의 데이터는 '필드'로 존재.
이 '필드'는 '인스턴스 필드'임. >>객체 안에 존재하니까 당연
따라서 static 키워드 X

  • Singleton 객체 테스트 1
public static void main(String[] args) {
	/*
	 * Singleton obj1 = new Singleton(); //컴파일 에러
	 * Singleton obj2 = new Singleton(); //컴파일 에러
	 */
		
	//싱글톤 객체 레퍼런스 얻기
	Singleton obj1 = Singleton.getInstance();
	Singleton obj2 = Singleton.getInstance();
		
	// 동등비교연산자를 참조변수에 수행할 때에는, 두 참조변수에 있는 주소값을 비교하는 것!
	if (obj1 == obj2) {
		log.info("같은 Singleton 객체 입니다.");
	}else {
		log.info("다른 Singleton 객체 입니다.");
	} //if-else
}//main

->> 같은 객체임을 확인할 수 있다.

  • Singleton 객체 테스트 2
public static void main(String[] args) {
	/*
	 * Singleton obj1 = new Singleton(); //컴파일 에러
	 * Singleton obj2 = new Singleton(); //컴파일 에러
	 */
		
	for(int i=1; i<=10; i++) {
		Singleton obj = Singleton.getInstance();
		log.info(String.format("[%d] obj : [%s]", i, obj));
	}//for
		
}//main


->> 레퍼런스 값 같음. (OID같다)

좋은 웹페이지 즐겨찾기