美文网首页
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