Programing/Design Patterns

Java BlockingQueue 활용 로그 출력 Producer-Consumer 패턴

리커니 2020. 8. 21. 18:01
반응형

Java BlockingQueue 활용 로그 출력Java BlockingQueue 활용 로그 출력 Producer-Consumer 패턴

 

Producer-Consumer 패턴은 말 그대로 생산, 소비 패턴입니다.

Producer가 Task 또는 Data를 생산해서 Queue 로 전달을 하고,

전달받은 Queue는 FIFO(First In First Out) 형태로 동시성을 관리하게 됩니다.

Consumer는 Queue의 Task나 Data를 전달 받아 소비하는 것이죠.

 

이번 포스팅에서는 BlockingQueue를 사용해서 P-C 패턴을 구현해 보겠습니다.

 

CmmnVar이라는 클래스에 static 으로 선언된 size 가 10인 BlockingQueue가 있습니다.

 

[CmmnVar.java]

public class CmmnVar {
	public static BlockingQueue<String> queue = new ArrayBlockingQueue<String>(10);
}

 

이제 이 큐에 String 데이터를 전달할 Producer를 작성합니다.

 

[Producer.java]

import kr.co.cmmn.CmmnVar;

public class Producer implements Runnable {

	private int value;
	
	public Producer(int value) {
		super();
		this.value = value;
	}

	@Override
	public void run() {
		for(int i=0; i<10; i++) {
			try {
				CmmnVar.queue.put(""+value);
				Thread.sleep(10);
			} catch (InterruptedException e) {
				Thread.currentThread().interrupt();
			}
		}
	}
}

 

10번을 반복하면서 BlockingQueue에 값을 넣는 클래스 입니다. 특별한 건 없죠.

이제 이 Queue의 데이터를 소비하는 Consumer 코드를 보도록 하겠습니다.

 

[Consumer.java]

import kr.co.cmmn.CmmnVar;

public class Consumer implements Runnable{
	@Override
	public void run() {
		String value;
		try {
			while((value = CmmnVar.queue.take()) != "exit") {
				System.out.println(value+"  //  "+CmmnVar.queue.size());
				Thread.sleep(10);
			}
		} catch (InterruptedException e) {
			log.error("Pring Log Thread Interrupted Exception", e);
			Thread.currentThread().interrupt();
		}
	}
}

 

Consumer 에서는 value가 "exit" 가 아닐 경우 queue의 take 메소드를 사용하여 값을 꺼내고 print하게 됩니다.

이제 실행을 해보도록 하죠.

 

[실행코드]

 Producer producer1 = new Producer(1);
 Producer producer2= new Producer(2);
 new Thread(producer1).start();
 new Thread(producer2).start();
 Consumer consumer = new Consumer();
 new Thread(consumer).start();

 

2개의 Producer 가 생산을 하고 1개의 Consumer가 소비를 하게됩니다. 

 

1  //  1
2  //  2
2  //  2
1  //  3
1  //  3
2  //  6
2  //  7
1  //  8
1  //  9
2  //  10
1  //  9
2  //  8
2  //  7
1  //  6
2  //  5
1  //  4
2  //  3
1  //  2
1  //  1
2  //  0

 

보시면 큐의 갯수가 증가하다가 다시 감소하는는 것을 보실 수 있습니다. 

Queue 에서 동시성을 제어하기 때문에 복수의 Producer와 Consumer 처리가 가능하게 됩니다.

반응형