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() { ... }