코딩하렴

DESIGN-PATTERN :: Singleton Pattern 싱글톤 패턴

by 으렴
public class Singleton {
	private static Singleton only_one;
	private Singleton() {}
	
	public static Singleton getInstance() {	//1번째 방법. 3번째 구문에 synchronized 추가 
		if(only_one==null) {
			synchronized (Singleton.class) {//2번째 방법. 이렇게 싱크로나이즈 한번만!
				if(only_one==null){
					only_one = new Singleton();
				}	
			}
		}
		return only_one;
	}
}

class Singleton_Main {

	public static void main(String[] args) {
		Singleton s1 = Singleton.getInstance();
		Singleton s2 = Singleton.getInstance();

		System.out.println(s1);
		System.out.println(s2);

	}
}

출력문에서는 같은 객체가 나온다.

 

싱글톤은 필요할 때마다 똑같은 인스턴스를 만들어 내는 것이 아니라, 이미 생성해둔 기존 인스턴스를 사용한다.

 

예를들어, 님덜 핸드폰 검색할때마다 핸드폰 구매하시나염?

 

그렇게 한다면 돈낭비져 이처럼 한개만 사용해도 되는 인스턴스를 계속해서 생성할 경우 메모리 낭비를 초래할 수 있다요.

 

싱글톤으로 만들면 클래스의 인스턴스는 전역 인스턴스이기 때문에 다른 클래스의 인스턴스들이 데이터 공유하기 쉽다요.

 

전역변수가 있지않나?라고 한다면!

 

전역변수는 한번도 사요되지 않을 경우에도 인스턴스가 생성된다.

 

전역변수로 선언한 객체가 자원을 많이 차지함에도 불구하고 프로그램이 실행되는 동안 한번도 사용되지 않는다면 자원 낭비일 것이다.

 

그에 비해 싱글톤은 최초 사용시까지 인스턴스 생성이 미뤄질 수 있다.

 

	private static Singleton only_one;
	
	private Singleton() {}
	
	public static Singleton getInstance() {	//3번째 synchronized 
		if(only_one==null) {
			only_one = new Singleton();
		}
		return only_one;
	}

 

만약 이런식으로 싱글톤 객체를 생성했다고 치자.

 

싱글 스레드라면 문제가 생기지 않겠지만 멀티스레드를 활용할 경우에는 문제가 생길 수도 있다.

 

동일한 시점에 같이 동시에 접근 할 가능성이 있기 때문이다.

 

예를들어 통장에 있는 만원을 엄마도 뽑고 나도 뽑고 2만원이 생기는 기적...♡

 

암턴 그라모 안대...

 

맨 위에 적어 놓은 코드처럼 synchronized 키워드를 적으면 아무래도 느려지거나 성능이 떨어질수도 있다.

 

holder를 사용하는 방법

public class Single_ {

	private static class holder{	//중첩클래스
		static final Single_ Instance__ = new Single_();
	}
	
	public static Single_ getInstance() {
		return holder.Instance__;
	}
}

중첩클래스(holder)는 getInstance 메서드가 호출되기 전에는 참조되지 않는다.

 

이를 통해 `일을 시킬 때만 메모리 할당` 할 수 있다.

 

1. holder안에 선언된 instance가 static이기 때문에 클래스 로딩 시점에 한번만 호출된다.

 

2. final을 사용해 값이 다시 할당되지 않도록 만든다.

 

 

Enum를 사용하는 방법

public class Single_ {

	private static class holder{	//중첩클래스
		static final Single_ Instance__ = new Single_();
	}
	
	public static Single_ getInstance() {
		return holder.Instance__;
	}
}

Enum 키워드는 고정된 상수들의 집합이며, 프로그램 내에서 한번만 실행되는 특징이 있다.

 

프로그램 내에서 한번만 실행되는 특징이 있다.

 

그리고 `상수`라서 한번 생성되면 변경될 수 없다.

 

이것을 javap명령어를 통해 원시코드로 역 어셈블 해 보면

 

enum으로 선언된 상수는 자동으로 static과 final속성이 붙는 것을 확인할 수 있다.

 

 

사이트의 정보

코딩하렴

으렴

활동하기