JAVA/999. 디자인패턴
디자인패턴#5 생산자/소비자 패턴( Producer/Consumer Pattern)
날아올라↗↗
2020. 11. 23. 17:32
728x90
반응형
[개요]
아래의 코드는 Linear( 선형큐)가 아닌 Circle Queue( 순환큐)를 이용하여 생산자/소비자 패턴을 구현해 보았습니다.
생산자/소비자 패턴은 멀티쓰레드 환경에서 주로 쓰이는 패턴입니다. 생산자와 소비자는 하나의 클래스를 공유하고 그 클래스는 큐구조를 가지게 됩니다.
생산자는 데이터를 지속적으로 만들어 큐에 넣을 것이고 소비자는 데이터를 지속적으로 큐에서 빼낼 것입니다.
[구조]
[Main.java]
package provider_consumer;
public class Main {
public static void main(String[] args) {
int size = 100;
Table table = new Table(100);
Thread provider = new Thread(new Provider(table));
Thread consumer = new Thread(new Consumer(table));
provider.start();
consumer.start();
}
}
[Table.java]
package provider_consumer;
public class Table {
private int[] queue;
private int capacity;
private int head;
private int tail;
private int count;
public Table(int capacity) {
this.capacity = capacity;
queue = new int[ capacity];
}
/**
* 큐에서 값을 하나 빼내는 메소드
* @return
* @throws InterruptedException
*/
public synchronized int pop() throws InterruptedException {
while( count <= 0) {
wait();
}
int retValue = queue[ tail];
tail = ( tail + 1) % queue.length;
count--;
notifyAll();
return retValue;
}
/**
* 큐에 값을 삽입하는 메소드
* @param ranNum
* @throws InterruptedException
*/
public synchronized void push(int ranNum) throws InterruptedException {
while( count >= queue.length) {
wait();
}
queue[ head] = ranNum;
head = ( head + 1) % queue.length;
count++;
notifyAll();
}
}
[Provier.java]
package provider_consumer;
public class Provider implements Runnable {
private Table table;
public Provider(Table table) {
this.table = table;
}
@Override
public void run() {
while( true) {
try {
int ranNum = ( int )(Math.random() * 100) + 1;
System.out.printf("입력 : %s \n", ranNum);
table.push( ranNum);
Thread.sleep(((int)(Math.random() * 500) + 1));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
[Consumer.java]
package provider_consumer;
public class Consumer implements Runnable {
private Table table;
public Consumer(Table table) {
this.table = table;
}
@Override
public void run() {
while( true) {
try {
int num = table.pop();
System.out.printf("출력 : %d \n", num);
Thread.sleep( ((int)(Math.random() * 500) + 1));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
728x90
반응형