Ⅰ.介绍

      已经两个月没有写博客了,网站的草已经三米高了😂。噩梦般的出差终于告一段落,暗示着除草行动的开启。
      生产者消费者模型(下文统称模型)与多线程相关的,因为有生产者、消费者至少两个线程。生产者把产品存放到商店,消费者到商店购买消费产品。为什么要推出这种类似中间商,而不是厂家直销,是因为生产者的生产效率和消费者的消费效率是不一样的,导致需要中间商存货。而效率的不同可以通过调整生产者与消费者的线程数来达到平衡。而模型产生的问题是生产者生产的产品足够多时,也就是说商店已经存满(一般来说系统的资源是有限的,所以商店是不可能存下无限多的产品),生产者该怎么去处理这个问题。另一种情况就是当商店里面没有产品的时候,消费者该怎么该如何应对。下面介绍的是通过阻塞队列来实现的模型。

Ⅱ.无码不欢😏

      LinkedBlockingQueue(这个的介绍放到下一篇文章吧)阻塞队列是用的ReentrantLock及Condition。解决了模型的上面所述的两种问题。

LinkedBlockingQueue queue = new LinkedBlockingQueue(100);
          try {
            while (!shop.producerDone() || !shop.consumerDone()) {
                //创建生产者线程
                while (producerNum < producerNumMax) {
                    Producer futureTask = new Producer(() -> {
                        shop.producer(queue);
                    });
                    proExecutor.execute(futureTask);
                    producerList.add(futureTask);
                    producerNum++;
                }
                //创建消费者线程
                while (consumerNum < consumerNumMax) {
                    Consumer futureTask = new Consumer(() -> {
                        shop.consumer(queue);
                    });
                    conExecutor.execute(futureTask);
                    consumerList.add(futureTask);
                    consumerNum++;
                }
                //判断生产者线程是否完成
                Iterator<FutureTask> proIterator = producerList.iterator();
                while (proIterator.hasNext()) {
                    if (proIterator.next().isDone()) {
                        producerNum--;
                        proIterator.remove();
                    }
                }
                //判断消费者线程是否完成
                Iterator<FutureTask> conIterator = consumerList.iterator();
                while (conIterator.hasNext()) {
                    if (conIterator.next().isDone()) {
                        consumerNum--;
                        conIterator.remove();
                    }
                }
            }
        } finally {//关闭线程池咯
            conExecutor.shutdown();
            proExecutor.shutdown();
        }

Ⅲ.总结

这只是一个简单的demo,有很多可以优化和拓展的地方,还需要慢慢迭代。模型的源码地址。先就酱,恰饭😋!