2

小さなアプリケーション (「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");
    }
}
4

1 に答える 1

1

これは私がスタックを書く方法です

public interface IntStack {
    void push(int value);
    int pop() throws InterruptedException;
}

public class DynamicStack implements IntStack {
    private int size = 0, stack[];

    public DynamicStack() {
        this(16);
    }

    public DynamicStack(int capacity) {
        stack = new int[capacity];
    }

    @Override
    public synchronized void push(int item) {
        if (size + 1 == stack.length)
            stack = Arrays.copyOf(stack, stack.length * 2);
        stack[size++] = item;
        notifyAll(); // notify() would also do.
    }

    @Override
    public synchronized int pop() throws InterruptedException {
        while (size == 0)
            wait();
        return stack[--size];
    }
}
于 2013-02-01T18:58:23.960 に答える