首页 文章

用Java实现 生产环境 者消费者

提问于
浏览
2

这是家庭作业的 生产环境 者消费者模式的实现 . 以下实现有什么问题 . 我已经google了各种实现,但我无法理解我的错误 .

我有一个共享队列,我在同一个锁上同步 生产环境 者和消费者

履行

Shared Queue:

class SharedQueue{
    public static Queue<Integer>   queue  = new LinkedList<Integer>();
 }

Producer Thread :

//The producer thread
class Producer implements Runnable{
    public void run()
    {
        synchronized (SharedQueue.queue)
        {
            if(SharedQueue.queue.size() >=5)
            {
                try {
                    SharedQueue.queue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            Random r  = new Random();

            int x = r.nextInt(10);
            System.out.println("Inside Producer" + x);

            SharedQueue.queue.offer(x);


            SharedQueue.queue.notify();

        }
    }
}

Consumer Thread:

class Consumer implements  Runnable{
    public void run()
    {
        synchronized (SharedQueue.queue)
        {
            if(SharedQueue.queue.size() == 0)
            {
                try {
                    SharedQueue.queue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                }
            }

            int k = SharedQueue.queue.remove();

            System.out.println("Inside consumer" + k);
        }
    }
}

The Main program

public class ProducerConsumerTest {

    public static void main(String[] args)
    {

        Thread p = new Thread(new Producer());
        Thread q = new Thread(new Consumer());

        p.start();
        q.start();

    }
}

4 回答

  • 1

    尝试更换:

    if(SharedQueue.queue.size() >= 5)
    

    有:

    while(SharedQueue.queue.size() >= 5)
    

    还有这个:

    if(SharedQueue.queue.size() == 0)
    

    有:

    while(SharedQueue.queue.size() == 0)
    

    只需在调用 notify() 后重新检查条件 .

  • 1

    我假设您希望这是 生产环境 者消费者的无限循环 . 在Eng.Fouad更改之上,将两个同步块替换为:

    while (true)
    

    并在Consumer中添加通知

    int k = SharedQueue.queue.remove(); 
    
            // make the producer active again
            SharedQueue.queue.notify();
    
            System.out.println("Inside consumer " + k);
    
  • 0

    实现 生产环境 者消费者问题的简单方法是使用信号量 .

    public class Semaphore {
        int value;
    
        public Semaphore(int intialValue) {
            this.value = intialValue;
        }
    
        public synchronized void p() {
            while (value <= 0) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                }
            }
            value = value - 1;
        }
    
        public synchronized void v() {
            value = value + 1;
            this.notify();
        }
    }
    
    public class ProducerConsumerUsingSemaphore {
    
        private static final int SIZE = 10;
    
        public static void main(String[] args) {
    
            Semaphore full = new Semaphore(0);
            Semaphore empty = new Semaphore(SIZE);
            Semaphore mutex = new Semaphore(1);
            Vector<Integer> sQueue = new Vector<Integer>();
    
            Thread producerThread = new Thread(new Runnable() {
    
                @Override
                public void run() {
    
                    for (int i = 0; i < 5000; i++) {
                        empty.p();
                        mutex.p();
                        System.out.println(Thread.currentThread().getName() + " is trying to insert item " + i);
                        sQueue.add(i);
                        mutex.v();
                        full.v();
                    }
                }
            });
    
            Thread consumerThread = new Thread(new Runnable() {
    
                @Override
                public void run() {
                    while (true) {
                        full.p();
                        mutex.p();
                        System.out.println(Thread.currentThread().getName() + " consuming item " + sQueue.remove(0));
                        mutex.v();
                        empty.v();
                    }
                }
            });
    
            producerThread.setName("Producer");
            consumerThread.setName("Consumer");
    
            consumerThread.start();
            producerThread.start();
    
        }
    }
    
  • 4

    您可以使用ConcurrentLinkedQueue来管理Producer和Consumer的共享队列 . 您可以使用ConcurrentHashMap> collection,它将帮助Producer同时生成,并且Consumer可以同时使用并将生成的密钥保存在另一个集合对象中,其中Consumer可以找到它的密钥并从ConcurrentHashMap>中使用它 .

相关问题