制片人 - 消费者Scenerio。我有一个生产者和多个消费者

时间:2016-01-22 15:32:53

标签: java multithreading collections producer-consumer

当生产者生成消息时,它必须由所有消费者使用,然后只有生产者可以生成第二个消息,并且所有消费者都必须消费它,依此类推。 我尝试编写这段代码,但它不按照要求工作。任何人都可以帮忙吗?

 package Demo3;

    import java.util.concurrent.Semaphore;

    public class ConsumerProducerMonitor {

        // produces items
        public synchronized void put(String item,int itemNo,String threadName) {
            if (isProduced) {
                return;

            }

            this.itemNo = itemNo;
            this.item=item;
            System.out.println(isProduced+"hujj");
            System.out.println("Producer " + threadName + " put Item: " + this.item);

            if (this.itemNo == 0) {
                isProduced = true;
                System.out.println(isProduced);
                this.notifyAll();
            }

        }
        int flag=10;
        private void consumeItems(String threadName) {
        System.out.println("hre i m");
          //  for (int i = 0; i < 2; ++i) {
              if (itemNo < 0) 
                   return;

              flag--;
           // }
            System.out.println("Consumer " + threadName + " consumed Items from " + this.item);
            if (!sem.tryAcquire()) {
                System.out.println("Failed to aquire semaphore for consumer: " + threadName);
            }
        }

        // consumes item
        public synchronized int get(String threadName) {
            if (!isProduced) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    System.out.println("Caught Interrupted Exceptino while waiting to consume item: " + e.getMessage());
                }
            }

            if (flag == 0) {
              //  sem.release(NUM_SEMAPHORES);
                return this.itemNo;
            }

            if (isConsuming) {
                try {
                    this.wait();
                    isConsuming = true;
                } catch (InterruptedException e) {
                    System.out.println("Caught Interrupted Exceptino while waiting to consume item: " + e.getMessage());
                }
            }

            switch (sem.availablePermits()) {
                case 1:
                    if (threadName.equals("C10")) {
                        System.out.println("reaching");
                        consumeItems(threadName);
                        if (threadName.equals("C10")) {
                            sem.release(NUM_SEMAPHORES);
                        }
                    }
                    break;
                case 2:
                    if (threadName.equals("C9")) {
                        consumeItems(threadName);
                    }
                    break;
                case 3:
                    if (threadName.equals("C8")) {
                        consumeItems(threadName);
                    }
                    break;
                case 4:
                    if (threadName.equals("C7")) {
                        consumeItems(threadName);
                    }
                    break;
                case 5:
                    if (threadName.equals("C6")) {
                        consumeItems(threadName);
                    }
                    break;
                case 6:
                    if (threadName.equals("C5")) {
                        consumeItems(threadName);
                    }
                    break;
                case 7:
                    if (threadName.equals("C4")) {
                        consumeItems(threadName);
                    }
                    break;
                case 8:
                    if (threadName.equals("C3")) {
                        consumeItems(threadName);
                    }
                    break;
                case 9:
                    if (threadName.equals("C2")) {
                        consumeItems(threadName);
                    }
                    break;
                case 10:
                    if (threadName.equals("C1")) {
                        consumeItems(threadName);
                    }
                    break;
                default:
                    break;
            }
          //  isConsuming = false;
            this.notifyAll();
            return flag;
        }

        private static int NUM_SEMAPHORES =10;
        private final Semaphore sem = new Semaphore(NUM_SEMAPHORES);
        private boolean isProduced = false;
        private boolean isConsuming = false;
        String item;
        int itemNo;
    }





    package Demo3;

    import java.util.ArrayList;
    import java.util.List;
    import java.util.Vector;

    public class ConsumerProducer5 {
        public static void main(String[] args) {
            ConsumerProducer5 cp = new ConsumerProducer5();
            cp.StartconsumerProducer();
        }


        public void StartconsumerProducer() {
            ConsumerProducerMonitor mon = new ConsumerProducerMonitor();
            List threads = new ArrayList();
            Vector sharedQueue = new Vector();
            // Create a producer
            Thread p1 = new Thread(new Producer5(sharedQueue,mon,20), "P1");
            p1.start();
            // Create consumer 1
            Thread c10 = new Thread(new Consumer5(mon,sharedQueue), "C10");
            c10.start();
            System.out.println("working");
            // Create consumer 2
            Thread c2 = new Thread(new Consumer5(mon,sharedQueue), "C2");
            c2.start();
            System.out.println("working321");
            // Create consumer 3
            Thread c3 = new Thread(new Consumer5(mon,sharedQueue), "C3");
            c3.start();
            Thread c4 = new Thread(new Consumer5(mon,sharedQueue), "C4");
            c4.start();
            Thread c5 = new Thread(new Consumer5(mon,sharedQueue), "C5");
            c5.start();
            Thread c6 = new Thread(new Consumer5(mon,sharedQueue), "C6");
            c6.start();
            Thread c7 = new Thread(new Consumer5(mon,sharedQueue), "C7");
            c7.start();
            Thread c8 = new Thread(new Consumer5(mon,sharedQueue), "C8");
            c8.start();
            Thread c9 = new Thread(new Consumer5(mon,sharedQueue), "C9");
            c9.start();
            Thread c1 = new Thread(new Consumer5(mon,sharedQueue), "C1");
            c1.start();
            threads.add(p1);
            threads.add(c1);
            threads.add(c2);
            threads.add(c3);
            threads.add(c4);
            threads.add(c5);
            threads.add(c6);
            threads.add(c7);
            threads.add(c8);
            threads.add(c9);
            threads.add(c10);


            for (int i = 0; i < threads.size(); ++i) {
                try {
                    ((Thread)threads.get(i)).join(20000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }


package Demo3;

import java.util.Vector;

public class Consumer5 implements Runnable {
    private final Vector sharedQueue;
    Consumer5(ConsumerProducerMonitor mon,Vector sharedQueue) {
        this.mon = mon;
        this.sharedQueue=sharedQueue;
    }

    @Override
    public void run() {
        System.out.println("coming hre");
        int ret=1;
        while (ret >= 1) {
            ret = mon.get(Thread.currentThread().getName());
            while (ret == 1) {
            synchronized (sharedQueue) {

                    try {
                        sharedQueue.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                    sharedQueue.notifyAll();
                }

            }
        }
    }

    private final ConsumerProducerMonitor mon;
}

package Demo3;

import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;



public class Producer5 implements Runnable {
    ConsumerProducerMonitor mon;
    private final Vector sharedQueue;
    private final int SIZE;

    public Producer5(Vector sharedQueue,ConsumerProducerMonitor mon, int size) {
        this.sharedQueue = sharedQueue;
        this.SIZE = size;
        this.mon=mon;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println("Produced: " + i);
         //   mon=new ConsumerProducerMonitor();


            try {
                produce(i);
            } catch (InterruptedException ex) {
                Logger.getLogger(Producer5.class.getName()).log(Level.SEVERE, null, ex);
            }

        }
    }

    private void produce(int i) throws InterruptedException {

        //wait if queue is full
        while (sharedQueue.size() == 1) {
           synchronized (sharedQueue) {
                  System.out.println("Queue is full " + Thread.currentThread().getName()
                                    + " is waiting , size: " + sharedQueue.size());

                sharedQueue.wait();
           }
        }

        //producing element and notify consumers
        synchronized (sharedQueue) {
            sharedQueue.removeAllElements();
            sharedQueue.add("Message No."+i);
            mon.put(sharedQueue.get(i).toString(),i, Thread.currentThread().getName());
            System.out.println(sharedQueue);
            sharedQueue.notifyAll();
        }

    }

}

1 个答案:

答案 0 :(得分:-1)

您的代码中有很多东西是不需要的。我们可以用更少的东西完成手头的任务。

基本上,这里的概念是生产者生产产品,通知所有消费者,然后等待自己。

另一方面,消费者每个消费产品并等到最后一个消费者消费产品,认识到它是最后一个消费者并通知生产者开始生产。

这是处理您的要求的代码。

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicInteger;

public class ProducerConsumerMultiple {

static Queue<String> sharedQueue = new LinkedList<>();

public static void main(String args[]) {

    Producer producer = new Producer("Producer1");
    Consumer consumer1 = new Consumer("Consumer1");
    Consumer consumer2 = new Consumer("Consumer2");
    Consumer consumer3 = new Consumer("Consumer3");
    Consumer consumer4 = new Consumer("Consumer4");
    Consumer consumer5 = new Consumer("Consumer5");
    new Thread(producer).start();
    new Thread(consumer1).start();
    new Thread(consumer2).start();
    new Thread(consumer3).start();
    new Thread(consumer4).start();
    new Thread(consumer5).start();
}

public static class Producer implements Runnable {
    String producerName;
    AtomicInteger itemNameCounter = new AtomicInteger(0);

    public Producer(String producerName) {
        this.producerName = producerName;
    }

    public void produce() throws InterruptedException {
        synchronized (sharedQueue) {
            System.out.println(producerName + " has produced item" + itemNameCounter.incrementAndGet());
            sharedQueue.add("item" + itemNameCounter.get());//adding the product to the queue
            sharedQueue.notifyAll();
            sharedQueue.wait();
        }
    }

    @Override
    public void run() {
        while (true) {
            try {
                produce();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public static class Consumer implements Runnable {
    String consumerName;
    static AtomicInteger totalConsumersCount = new AtomicInteger(0);
    static Integer consumptionCountForItem = 0;

    public Consumer(String consumerName) {
        this.consumerName = consumerName;
    }

    public void consume() throws InterruptedException {

        synchronized (sharedQueue) {
            if (sharedQueue.size() <= 0) {
                sharedQueue.wait();
            }

            System.out.println(consumerName + " has " + "consumed " + sharedQueue.peek());// Consumer is consuming the item.

            if (++consumptionCountForItem == totalConsumersCount.get()) {
                sharedQueue.remove();
                sharedQueue.notifyAll();
                consumptionCountForItem = 0;
            }
            sharedQueue.wait();
        }
    }

    @Override
    public void run() {
        totalConsumersCount.incrementAndGet();
        while (true) {
            try {
                consume();
            } catch (InterruptedException e) {
                e.printStackTrace();
                totalConsumersCount.decrementAndGet();
            }
        }
    }
}
}