Java 객체지향 디자인 패턴 6장 싱글턴

필자의 해석이 포함되어 있습니다!
실제로 책에서 의도한 의미와는 다를 수 가 있습니다
주의 부탁드립니다 !!

6장 : Singleton 싱글턴


실행부

Printer printer = Printer.getInstance();
printer.print();

Printer printer2 = Printer.getInstance();
printer2.print();

프린터

public class Printer {

	private static Printer printer;

	private Printer() {
		System.out.println("new printer ! ");
	}

	public static Printer getInstance() {
		if (printer == null) {
			printer = new Printer();
		}
		return printer;
	}

	public void print() {
		System.out.println("print it ! by " + printer.toString());
	}
}

실행결과

new printer !
print it ! by designpattern.singletone.Printer@7a79be86
print it ! by designpattern.singletone.Printer@7a79be86

문제점

본래 하나만을 생성해서 관리를 하려던 의도로 작성된 것인데

멀티 쓰레드 환경에서 객체 생성시 경합이 일어나 여러 인스턴스가 생성될 수 있다

  • 경합 조건 (race condition) 이란 2개 이상의 쓰레드가 메모리와 같은 자원을 동시에 이요하려고 하는 현상이다
public class SingletonMain {

	static class User extends Thread {

		public User(String name) {
			super(name);
		}

		@Override
		public void run() {
			print();
		}

		private void print() {
			Printer printer = Printer.getInstance();
			printer.print();
		}
	}

	static class Printer {
		private static Printer printer;

		public static Printer getInstance() {
			if (printer == null) {
				try {
					Thread.sleep(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				printer = new Printer();
			}
			return printer;
		}

		public void print() {
			System.out.println("print it ! by " + printer);
		}
	}

	public static void main(String[] args) {
		User[] users = new User[5];
		for (int i = 0; i < users.length; i++) {
			users[i] = new User("user-thread" + i);
			users[i].start();
		}
	}
}

실행결과

print it ! by designpattern.singletone.SingletonMain$Printer@64c2d94c
print it ! by designpattern.singletone.SingletonMain$Printer@597fa211
print it ! by designpattern.singletone.SingletonMain$Printer@64c2d94c
print it ! by designpattern.singletone.SingletonMain$Printer@5451414f
print it ! by designpattern.singletone.SingletonMain$Printer@597fa211

위와 같이 여러개의 싱글턴 객체가 생성된다 즉 싱글턴이 아니다 하하하

해결책

  • 정적 변수에 인스턴스를 만들어 바로 초기화하는 방법
private static Printer printer = new Printer();
  • 인스턴스 생성 메서드에 동기화하는 방법
public synchronized static Printer getInstance() { ... }




© 2020.12. by 따라쟁이

Powered by philz