如何实现多个生产者和消费者? -Java

时间:2019-06-28 10:02:16

标签: java multithreading producer-consumer

这是任务:使用2种方法创建通用ArrayBlockingQueue类: -put(E e)将指定的元素插入此队列的末尾,等待空间变为 如果队列已满,则可用。 -take()-检索并删除此队列的头,如有必要,请等待直到元素 变得可用。 使用wait和notify / notifyAll方法。容量应为类的参数 构造函数。 创建一个接受大量使用者作为运行时参数的主程序。创建 线程–消费者和生产者。启动程序时,生产者线程应为 等于传递给程序的参数。生产者线程应从stdin中读取 并使用put方法将数据发送到队列。消费者应获取数据并打印 格式为“线程1-<数据>”

重要提示:请禁止以下类的使用-线程池, 执行器,可调用,可运行,未来

我不知道为什么“代码”部分出了问题...

到目前为止,我已经执行了以下操作: 创建了ArrayBlockingQueue类,在其中实现了put(E e)和take()方法。 类生产者将元素放入队列,类消费者从队列中取出要素。

我将队列容量设置为5,并正在向队列中一个接一个地添加8个元素。通过这种方式,我正在测试消费者是否将为我释放空间来放置下一个元素。当我将所有8个元素放入队列时,我将从队列中取出所有剩余的元素并进行打印。

问题是我不知道如何使N-生产者数量和N-消费者数量。

import java.util.LinkedList;

public class ArrayBlockingQueue<E> {
    private boolean printAll;
    private Object lock = new Object(); //  Alternative I can use ArrayList.class.wait() and ArrayList.class.notifyAll();
    private Integer capacity;
    private LinkedList<E> queue = new LinkedList<>();

    //  The capacity should be a parameter to the class constructor
    ArrayBlockingQueue(Integer capacity) {
        this.capacity = capacity;
    }

    void put(E element) throws InterruptedException {
        //  Do not put elements in the queue if it`s full
        while (capacity == queue.size()) {
            synchronized (lock) {
                lock.wait();
            }
        }
        queue.add(element);
        synchronized (lock) {
            lock.notify();
        }
    }

    E take() throws InterruptedException {
        E element;
        //  Do not take elements while queue is not full
        while ((queue.isEmpty() || queue.size() < capacity) && !printAll) {
            synchronized (lock) {
                lock.wait();
            }
        }
        //  make this thread wait / Else remove() will try to take from an empty queue
        if (queue.isEmpty() && printAll){
            synchronized (lock) {
                lock.wait();
            }
        }
        element = queue.remove();
        synchronized (lock) {
            lock.notify();
        }
        return element;
    }

    void waitThread() throws InterruptedException {
        synchronized (lock) {
            lock.wait();
        }
    }

    synchronized int getQueueSize (){
        return queue.size();
    }

    void setPrintAll(boolean printAll) {
        this.printAll = printAll;
    }

    Integer getCapacity() {
        return capacity;
    }

}




import java.util.Scanner;

public class Producer extends Thread {
    private ArrayBlockingQueue<Integer> queue;

    //  Assigning the queue from main so that
    //  Prod and Cons work with the same resources
    Producer(ArrayBlockingQueue<Integer> queue) {
        this.queue = queue;
    }

    public synchronized void run() {
        //  The size of the queue is 5 elements [declared in main] here I am trying to put 8
        //  so the producer HAS to wait for the Consumer to take some elements
        //  in order to put a new element
        System.out.println("\nBlocking queue capacity [" + queue.getCapacity() + "] Trying to add 8 elements.");
        try {
            Scanner scanner = new Scanner(System.in);
            for (int i = 0; i < 8; i++) {
                System.out.println(Thread.currentThread().getName() + "] Enter element:");
                Integer inputElement = scanner.nextInt();
                queue.put(inputElement);
                System.out.println("Queue size [" + queue.getQueueSize() + "]");
            }

            queue.setPrintAll(true);
            queue.waitThread();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}


public class Consumer extends Thread {
    private ArrayBlockingQueue<Integer> queue;

    //  Assigning the queue from main so that
    //  Prod and Cons work with the same resources [same queue]
    Consumer(ArrayBlockingQueue<Integer> queue){
        this.queue = queue;
    }
    public synchronized void run(){
        try {
            while (true) {
                System.out.println(Thread.currentThread().getName() + " - data<" + queue.take() + ">");
                System.out.println("Queue size [" + queue.getQueueSize() + "]");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


public class MainApp {
    public static void main(String[] args) throws InterruptedException {
        if (args.length == 0) {
            throw new RuntimeException("No program arguments detected. Operation aborted.");
        }
        //  Create a main program that accepts number of consumers as runtime argument.
        Long numberOfConsumers = Long.valueOf(args[0]);
        //  Create ArrayBlockingQueue with capacity of 5 elements
        ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(5);

        //  Creating new thread Producer and passing the queue
        //  Creating new thread Consumer and passing the queue

        Producer producerOne = new Producer(queue);
        Consumer consumerOne = new Consumer(queue);


        producerOne.start();
        consumerOne.start();

        producerOne.join();
        consumerOne.join();
    }
}

这些是我现在的结果。 1个生产者和1个消费者一切正常。如何制作多种产品。

Blocking queue capacity [5] Trying to add 8 elements.
Thread-0] Enter element:
10
Queue size [1]
Thread-0] Enter element:
20
Queue size [2]
Thread-0] Enter element:
30
Queue size [3]
Thread-0] Enter element:
40
Queue size [4]
Thread-0] Enter element:
50
Queue size [5]
Thread-0] Enter element:
Thread-1 - data<10>
Queue size [4]
60
Queue size [5]
Thread-0] Enter element:
Thread-1 - data<20>
Queue size [4]
70
Queue size [5]
Thread-0] Enter element:
Thread-1 - data<30>
Queue size [4]
80
Queue size [5]
Thread-1 - data<40>
Queue size [4]
Thread-1 - data<50>
Queue size [3]
Thread-1 - data<60>
Queue size [2]
Thread-1 - data<70>
Queue size [1]
Thread-1 - data<80>
Queue size [0]

0 个答案:

没有答案