Java中的多个生产者和消费者问题(没有BlockingQueue)

3as*_*awy 2 java concurrency pthreads

我正在刷新我对Java并发性的记忆,我正在玩流行的生产者消费者问题.我已经实现了以下代码,如果有一个生产者和一个消费者,它可以正常工作.但是,如果有多个生产者/消费者,它将无法正常运行.我不明白为什么

public class ProducerConsumer {

    static Monitor monitor;

    public ProducerConsumer(int maxSize)
    {
        monitor = new Monitor(maxSize);
        new Producer().start();
        new Producer().start();
        new Consumer().start();
        new Consumer().start();
    }

    class Producer extends Thread{

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

    class Consumer extends Thread{

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

     class Monitor {

          int n;
          int maxSize;

         public Monitor(int maxSize)
         {
             n=0;
             this.maxSize = maxSize;
         }

        synchronized void insert() throws InterruptedException 
        {
            if(n==maxSize)
                wait();
            System.out.println("Producer: "+n++);
            if(n==1)
                notifyAll();
        }

        synchronized void remove() throws InterruptedException 
        {
            if(n==0)
                wait();
            System.out.println("Consumer: "+n--);
            if(n==maxSize-1)
                notifyAll();
        }
    }

    public static void main(String[] args) {
        ProducerConsumer pc = new ProducerConsumer(100);

    }
}
Run Code Online (Sandbox Code Playgroud)

axt*_*avt 8

wait() 应始终以下列方式使用:

while(condition not met) 
    wait();
Run Code Online (Sandbox Code Playgroud)

否则一些线程可以唤醒并在条件仍未满足时继续.这种情况有两种可能的原因:

  1. 当你调用时notifyAll(),你唤醒所有等待的线程,因此当条件再次为假时(即当有限的资源已被其他线程耗尽时),其中一些可能为时已晚.
  2. 有可能出现虚假的唤醒(即线程在没有相应的情况下唤醒notify).

如果你实际上只需要唤醒一个线程,你可以使用notify()而不是notifyAll().它消除了第一个问题,但仍然无法保护您免受虚假唤醒,因此while仍然需要.