BlockingQueue라는 아주 유용한 클래스가 있습니다.

몰랐을땐 큐 클래스를 만들어 synchronized를 사용하여 동기화 시켜주는 작업을 했었는데...... 

진작에 알았으면 생성자, 소비자 패턴을 쉽게 구현 했을텐데...ㅡㅜ


이제 부터라도 잘 사용하도록 까먹지 않도록 하기 위해 샘플을 만들어 봤습니다.


[샘플소스]

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
 
public class TestBlockingQ {
 
	/**
	 * 생산자 클래스
	 * @author falbb
	 *
	 */
	static class Producer implements Runnable {
		private BlockingQueue<String> queue;
 
		public Producer(BlockingQueue<String> queue) {
			this.queue = queue;
		}
 
		@Override
		public void run() {
 
			// 날짜 포멧
			SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
 
			Date date = null;
 
			while(true) {
				try {
 
					date = new Date();
					// 큐에 넣기
					queue.put(dateFormat.format(date));
 
					// 큐 사이즈 출력
					System.out.printf("[%s] : size = %d \n", Thread.currentThread().getName(), queue.size());
 
					// 대기시간
					Thread.sleep(200);					
 
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
 
	}
 
	/**
	 * 소비자 클래스
	 * @author falbb
	 *
	 */
	static class Consumer implements Runnable {
 
		private BlockingQueue<String> queue;
		public Consumer(BlockingQueue<String> queue) {
			this.queue = queue;
		}
 
		@Override
		public void run() {
 
			while(true) {
				try {
 
					System.out.printf("[%s] : %s \n",Thread.currentThread().getName(), queue.take());
 
					// 대기 시간
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
 
	}
 
 
	/**
	 * @param args
	 */
	public static void main(String[] args) {
 
		// BlockingQueue사용 방법
		// ex1)BlockingQueue<String> queue = new ArrayBlockingQueue<String>(큐의 맥스 사이즈);
		// ex2)BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
		BlockingQueue<String> queue = new ArrayBlockingQueue<String>(50);
 
		Thread producer = new Thread(new Producer(queue));
		producer.setName("생산자1");
		producer.start();
 
		for (int i = 0; i < 5; i++) {
			Thread consum = new Thread(new Consumer(queue));
			consum.setName("소비자"+(i+1));
			consum.start();
		}
 
	}
 
}



[실행 결과]

TestBlockingQ.PNG



BlockingQueue사용 방법에 대해 좀더 설명을 부가 하자면.....

 ArrayBlockingQueue로생성시 큐사이즈를 50으로 하고 큐에 넣을때 queue.put()를 사용할때와 queue.add()를 사용할때

틀린 점이 있습니다. 예제 소스에서는 queue.put()을 사용 했는데....


put의 경우는 큐사이즈가 50을 넣어가면 넣을수 있는 자리가 비일 때까지 기다리지만, add의 경우는 Exception이 발생합니다.

그건 여러분이 한번 바꿔서 해보세요.


LinkedBlockingQueue로 생성시에는 큐사이즈를 지정할 수 도 있지만,  지정 하지 않아도 되니...

어떤 차이가 있는지 여러분이 한번 테스트 해보세요. ^^;


감사합니다.