[CHAPTER 4] 실무 활용 패턴 (중) + 과제리뷰
지난 시간 Instance 수를 제한하는 Singleton 패턴을 배웠었고, 과제로 한 개의 Instance 만 제한하는 것이 아닌 특정 개수만큼의 Instance 를 제한하는 Multiton 을 만들어 보도록 하였습니다.
관련 내용은 아래 포스팅을 참고!
2017/05/08 - [일상/[STUDY] OOP & FP 연구] - [CHAPTER 4] 실무 활용 패턴 (중)
2017/05/14 - [일상/[STUDY] OOP & FP 연구] - [ChAPTER 4] 실무 활용 패턴 (중) [Singleton 패턴] + 추가내용
2017/05/14 - [일상/[STUDY] OOP & FP 연구] - [CHAPTER 4] 실무 활용 패턴 (중) + 과제
똑똑한 우리 스터디 구성원 모두 과제를 잘해왔고, 정리하는 차원에서 제가 만든 Multiton 을 Review 해보도록 하겠습니다.
일단 가정은 요구사항의 SetInstanceCount 시점에 Instance pool 을 만드는 것이 아닌(Eager-binding), 개수만 먼저 제한하고 필요시점마다 Instance 를 생성하는 게으른 할당(Lazy-binding)으로 제작해 보겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | public class Multiton { // INSTANCE POOL 관리. // 어떤 세팅도 하지 않았으면, Singleton 으로 관리하도록 처리. private static int INSTANCE_LIMIT_COUNT = 1; // Instance pool. private static HashMap<Integer, Multiton> POOL = new HashMap<>(); private static Integer toggleCount = 0; private String toStringMessage; /** * 외부에서 Instance 를 만들지 못하도록 접근제한. */ private Multiton(){ // Instance 의 생성과 함께 POOL 에 넣는다. Integer number = POOL.size(); toStringMessage = String.format("%d번 인스턴스", number); POOL.put(number, this); } /** * Instance 출력. * * <pre> * Lock 을 메소드에 모두 걸어 Thread-safe 를 보장. * </pre> * * @return */ public static synchronized Multiton GetInstance() { final Multiton result; if (POOL.size() < INSTANCE_LIMIT_COUNT) { // Instance 개수가 아직 제한된 POOL 만큼 생성안된 경우. result = new Multiton(); } else { // Instance 개수가 아직 제한된 POOL 만큼 생성 된 경우. result = POOL.get(toggleCount); toggleCount = (toggleCount + 1) % INSTANCE_LIMIT_COUNT; } return result; } /** * 인스턴스의 개수 제한 * * @param limitCount */ public static final void SetInstanceCount(int limitCount) { if (limitCount < 0) { throw new RuntimeException("[에러] Instance 개수는 0보다 커야 합니다."); } INSTANCE_LIMIT_COUNT = limitCount; } @Override public String toString(){ return toStringMessage; } } | cs |
코드 내부의 구체적인 주석을 명시 하였고, 주의깊게 봐야할 부분은 아래와 같습니다.
1. Thread-safe 보장을 위해 Instance 를 유일하게 외부로 내보낼 수 있는 GetInstance 메소드에 synchronized 키워드를 달았습니다.
2. 사용자가 SetInstanceCount 를 사용하지 않을 수 있기 때문에 Instance 개수 제한을 명시적으로 1로 초기화하였습니다.
(INSTANCE_LIMIT_COUNT = 1)
이렇게 제작된 코드를 Thread-safe 가 보장이 되는지 확인해보도록 하겠습니다.
아래 테스트는 Thread 를 50 개 제작하여, 실행하는 메소드입니다. 각 스레드에서는 각 Instance 의 toStringMessage 를 출력하도록 합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | // Thread Test using JAVA7 { System.out.println("멀티톤 테스트!!"); Multiton.SetInstanceCount(5); // Thread 목록 생성. final ArrayList<Thread> multiThreadTestList = new ArrayList<>(); { for (int i = 0; i < 50; ++i) { Thread newThread = new Thread(new Runnable() { @Override public void run() { System.out.println(Multiton.GetInstance()); } }); multiThreadTestList.add(newThread); } } // Thread 실행 { // Thread 생성 즉시 바로 실행하지 않고, 목록을 생성하고 실행하는 이유는 최대한 동시에 Thread 를 실행하고 싶기 때문! // Thread Instance 를 만드는 시간 때문에 제대로 테스트가 안될 가능성 존재. for (Thread thread : multiThreadTestList) { thread.start(); } } } // Thread Test using JAVA8 { IntStream.rangeClosed(0, 50).mapToObj(n -> new Thread(() -> System.out.println(Multiton.GetInstance()))).forEach(Thread::start); } // CONSOLE LOG // 멀티톤 테스트!! // 0번 인스턴스 // 1번 인스턴스 // 2번 인스턴스 // 3번 인스턴스 // 4번 인스턴스 // 1번 인스턴스 // 3번 인스턴스 | cs |
CONSOLE LOG 를 보면, Instance 가 꼭 순서대로 나오지는 않는 것을 볼 수 있습니다.
비록 GetInstance 에서 LOCK 처리는 하였지만 Thread 의 실행 상태에 따라 순서가 바뀔 수는 있습니다.
순서를 보장해야만 한다면 Blocking 처리 등 더 복잡한 과정이 필요하겠지만, 이번 주제는 Instance 의 개수를 제한하는 것이니 다루지 않을 예정입니다.
이 블로그가 스터디를 참여하고 있는 모두에게 좋은 정보가 되길 바랍니다. :-)
'스터디 > [STUDY] OOP' 카테고리의 다른 글
[CHAPTER @] Break Time (잠깐 쉬는 후기) (0) | 2017.06.04 |
---|---|
[CHAPTER 4] 실무 활용 패턴 (중) [Adapter 패턴] + 추가내용 (0) | 2017.05.21 |
[CHAPTER 5] 실무 활용 패턴 (하) (0) | 2017.05.18 |
[CHAPTER 4] 실무 활용 패턴 (중) + 과제 (0) | 2017.05.14 |
[ChAPTER 4] 실무 활용 패턴 (중) [Singleton 패턴] + 추가내용 (0) | 2017.05.14 |