美文网首页
Condition实现生产者消费者模式的一点思考

Condition实现生产者消费者模式的一点思考

作者: 老王子H | 来源:发表于2018-11-11 12:30 被阅读0次

网上有人说为什么要用两个condition来实现生产者消费者模式

public class ProducerConsumerPattern {
  public static final int MAX_CAP = 1;
  static LinkedList<Object> list = new LinkedList<>();
  static ReentrantLock lock = new ReentrantLock();
  static Condition notFull = lock.newCondition();
  static Condition notEmpty = lock.newCondition();

  static class Producer implements Runnable {

      @Override
      public void run() {
          while (true) {
              try {
                  lock.lock();
                  while (list.size() == MAX_CAP) {
                      try {
                          System.out.println("当前已有" + list.size() + "个产品,缓冲区已满,请等待消费者消费");
                          notFull.await();
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
                  list.add(new Object());
                  System.out.println("生产了一个产品,当前产品个数为 " + list.size());
                  notFull.signal();
              } finally {
                  lock.unlock();
              }

          }
      }
  }

  static class Consumer implements Runnable {

      @Override
      public void run() {
          while (true) {
              try {
                  lock.lock();
                  while (list.size() == 0) {
                      try {
                          System.out.println("当前已有" + list.size() + "个产品,缓冲区已空,请等待生产者生产");
                          notFull.await();
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
                  list.remove();
                  System.out.println("消费了一个产品,当前产品个数为 " + list.size());
                  notFull.signal();
              } finally {
                  lock.unlock();
              }


          }
      }
  }

  public static void main(String[] args) throws InterruptedException {
      for (int i = 0; i < 3; i++) {
          new Thread(new Producer()).start();
          new Thread(new Consumer()).start();
      }

如果只有一个condition,通过代码演示,程序卡着不动了。


image.png

设置队列容量为1,
假设现在队列为空,条件队列里有3个消费者线程等待被唤醒


image.png

生产者生产了一个产品之后调用signal通知消费者去消费,常规逻辑条件队列最后一个节点会转移到阻塞队列,之后就准备获取锁了。只要重新获取到锁了以后,继续往下执行。


image.png

在并发环境下,还没来得及操作最后节点,此时生产者线程抢到了锁,发现队列满了,会调用await方法被阻塞,进入条件队列尾部。


image.png

然后signal方法将生产者线程
移除到阻塞队列去竞争锁,因为没有消费者消费,竞争到锁后发现队列还是满的,就会一直阻塞在那


image.png

如果有两个condition,那么就会有两个条件队列。生产者阻塞会进入生产者条件队列等待被唤醒,消费者阻塞会进入消费者条件队列,隔离开来,互不影响,就不会出现上述情况。

相关文章

网友评论

      本文标题:Condition实现生产者消费者模式的一点思考

      本文链接:https://www.haomeiwen.com/subject/jxyxfqtx.html