小さなアプリケーション (「HelloWorld」よりも少し大きいもの) を作成しています。タスクは、単一のプロデューサーと複数のコンシューマーを作成することです。プロデューサーは整数を生成し、それらを動的スタック (私のモニター オブジェクト) に配置し、コンシューマーはそれらの整数をスタックから取得しようとします。フラグを使用して 1 つのプロデューサー + 1 つのコンシューマーを作成し、内部で wait() を使用する方法を知っています。しかし、複数の消費者で同じことを行う方法。
私のコードを見てください:
public interface StackQueueIF {
void push(int value);
int pop();
}
public class DynamicStack implements StackQueueIF{
private volatile int stck[];
private volatile int tos;
boolean valueSet = false;
public DynamicStack(int size) {
stck = new int[size];
tos = -1;
}
@Override
public synchronized void push(int item) {
while(valueSet){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (tos == stck.length-1) {
System.out.println("---------STACK HAS BEEN DOUBLED--------");
int temp[] = new int[stck.length * 2];
for (int i = 0; i < stck.length; i++) temp[i] = stck[i];
stck = temp;
stck[++tos] = item;
}else
stck[++tos] = item;
valueSet = true;
notifyAll();
}
@Override
public synchronized int pop() {
while(!valueSet){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
valueSet = false;
notifyAll();
return stck[tos--];
}
}
class Producer implements Runnable{
StackQueueIF queue;
String producerName;
private static int counter = 0;
public Producer(StackQueueIF queue, String name) {
this.queue = queue;
this.producerName = name;
new Thread(this,producerName).start();
}
@Override
public void run() {
while(true){
System.out.println(this.producerName + " puts " + (++counter)
+ " into stack");
this.queue.push(counter);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.err.println(producerName + " interrupted");
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable{
StackQueueIF queue;
String consumerName;
public Consumer(StackQueueIF queue, String consumerName) {
this.queue = queue;
this.consumerName = consumerName;
new Thread(this, this.consumerName).start();
}
@Override
public void run() {
while(true){
System.out.println(this.consumerName + " gets " + queue.pop() + " from stack");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.err.println(consumerName + "interrupted");
e.printStackTrace();
}
}
}
}
public class QueueTester {
public static void main(String[] args) {
StackQueueIF queue = new DynamicStack(10);
new Producer(queue,"Producer №1");
new Consumer(queue,"Consumer №1");
new Consumer(queue,"Consumer №2");
}
}