Java并发编程与技术内幕:消费者-生产者模式研究

本文转载自http://blog.csdn.net/evankaka

1、生产者仅仅在仓储未满时候生产,仓满则停止生产。
2、消费者仅仅在仓储有产品时候才能消费,仓空则等待。
3、当消费者发现仓储没产品可消费时候会通知生产者生产。
4、生产者在生产出可消费产品时候,应该通知等待的消费者去消费。

      光看要求的话,应该不复杂。但是真正编程起来时,还是要考虑不少东西,本文将主要以三种方法来实现生产者-消费者模式:


一、wait/notify实现

    这是一种比较常规的实现方法,但是代码个人感觉有点复杂。并且缺点是不能完全实现仓储有产品马上就消费。代码如下:

[java]  view plain  copy
  1. package com.lin;  
  2.   
  3. import java.util.LinkedList;  
  4. import java.util.List;  
  5.   
  6. class Storehouse {  
  7.     // 仓库的容量  
  8.     private int capacity;  
  9.     // object当成是生产的商品  
  10.     private List<Object> list = new LinkedList<Object>();  
  11.   
  12.     public Storehouse(int capacity) {  
  13.         this.capacity = capacity;  
  14.         System.out.println("当前仓库产品数量:" + list.size());  
  15.     }  
  16.   
  17.     public int getCapacity() {  
  18.         return capacity;  
  19.     }  
  20.   
  21.     public void setCapacity(int capacity) {  
  22.         this.capacity = capacity;  
  23.     }  
  24.   
  25.     /** 
  26.      * 生产的方法 
  27.      *  
  28.      * @throws InterruptedException 
  29.      */  
  30.     public void produrce(int num) throws InterruptedException {  
  31.         // 同步方法  
  32.         synchronized (list) {  
  33.             // 仓库还未满,且再生产num个产品不会超过仓库容量时可以生产产品  
  34.             while (list.size() + num > this.capacity) {  
  35.                 // 仓库已满,或者放不下  
  36.                 System.out.println("【仓库已无法再生产:" + num + "个产品】" + "当前仓库产品数量:" + list.size());  
  37.                 list.wait();  
  38.   
  39.             }  
  40.   
  41.             System.out.println("【仓库还未满,生产:" + num + "个产品没有问题】" + "当前仓库产品数量:" + list.size());  
  42.             for (int i = 0; i < num; i++) {  
  43.                 list.add(new Object());  
  44.             }  
  45.             list.notifyAll();  
  46.         }  
  47.     }  
  48.   
  49.     /** 
  50.      * 消费 
  51.      *  
  52.      * @param num 
  53.      * @throws InterruptedException 
  54.      */  
  55.     public void consumer(int num) throws InterruptedException {  
  56.         // 同步方法  
  57.         synchronized (list) {  
  58.             // 仓库有没有num个产品可消费  
  59.             while (list.size() < num) {  
  60.                 System.out.println("【仓库没有:" + num + "个产品可消费】" + "当前仓库产品数量:" + list.size());  
  61.                 list.wait();  
  62.             }  
  63.             System.out.println("【仓库有:" + num + "个产品可消费】" + "当前仓库产品数量:" + list.size());  
  64.             for (int i = 0; i < num; i++) {  
  65.                 list.remove(0);  
  66.             }  
  67.             list.notifyAll();  
  68.         }  
  69.     }  
  70. }  
  71.   
  72.     class ProducerThread extends Thread {  
  73.         // 每次生产的产品数量  
  74.         private int num;  
  75.   
  76.         // 所在放置的仓库  
  77.         private Storehouse storehouse;  
  78.   
  79.         // 构造函数,设置仓库  
  80.         public ProducerThread(Storehouse storehouse, int num) {  
  81.             this.storehouse = storehouse;  
  82.             this.num = num;  
  83.         }  
  84.   
  85.         public void run() {  
  86.             try {  
  87.                 storehouse.produrce(num);  
  88.             } catch (InterruptedException e) {  
  89.                 e.printStackTrace();  
  90.             }  
  91.         }  
  92.     }  
  93.   
  94.     class ConsumerThread extends Thread {  
  95.         // 每次生产的产品数量  
  96.         private int num;  
  97.   
  98.         // 所在放置的仓库  
  99.         private Storehouse storehouse;  
  100.   
  101.         // 构造函数,设置仓库  
  102.         public ConsumerThread(Storehouse storehouse, int num) {  
  103.             this.storehouse = storehouse;  
  104.             this.num = num;  
  105.         }  
  106.   
  107.         public void run() {  
  108.             try {  
  109.                 storehouse.consumer(num);  
  110.             } catch (InterruptedException e) {  
  111.                 e.printStackTrace();  
  112.             }  
  113.         }  
  114.   
  115.     }  
  116.   
  117. public class Test1 {  
  118.   
  119.     public static void main(String[] args) {  
  120.   
  121.         // 仓库对象  
  122.         Storehouse storage = new Storehouse(1000);  
  123.   
  124.         // 生产者对象  
  125.         ProducerThread p1 = new ProducerThread(storage, 200);  
  126.         ProducerThread p2 = new ProducerThread(storage, 200);  
  127.         ProducerThread p3 = new ProducerThread(storage, 100);  
  128.         ProducerThread p4 = new ProducerThread(storage, 300);  
  129.         ProducerThread p5 = new ProducerThread(storage, 400);  
  130.         ProducerThread p6 = new ProducerThread(storage, 200);  
  131.         ProducerThread p7 = new ProducerThread(storage, 500);  
  132.   
  133.         // 消费者对象  
  134.         ConsumerThread c1 = new ConsumerThread(storage, 500);  
  135.         ConsumerThread c2 = new ConsumerThread(storage, 200);  
  136.         ConsumerThread c3 = new ConsumerThread(storage, 800);  
  137.   
  138.         // 线程开始执行  
  139.         c1.start();  
  140.         c2.start();  
  141.         c3.start();  
  142.         p1.start();  
  143.         p2.start();  
  144.         p3.start();  
  145.         p4.start();  
  146.         p5.start();  
  147.         p6.start();  
  148.         p7.start();  
  149.   
  150.     }  
  151.   
  152. }  

输出结果:

[plain]  view plain  copy
  1. 当前仓库产品数量:0  
  2. 【仓库没有:500个产品可消费】当前仓库产品数量:0  
  3. 【仓库没有:800个产品可消费】当前仓库产品数量:0  
  4. 【仓库还未满,生产:200个产品没有问题】当前仓库产品数量:0  
  5. 【仓库没有:800个产品可消费】当前仓库产品数量:200  
  6. 【仓库没有:500个产品可消费】当前仓库产品数量:200  
  7. 【仓库还未满,生产:300个产品没有问题】当前仓库产品数量:200  
  8. 【仓库有:500个产品可消费】当前仓库产品数量:500  
  9. 【仓库没有:800个产品可消费】当前仓库产品数量:0  
  10. 【仓库还未满,生产:200个产品没有问题】当前仓库产品数量:0  
  11. 【仓库没有:800个产品可消费】当前仓库产品数量:200  
  12. 【仓库有:200个产品可消费】当前仓库产品数量:200  
  13. 【仓库没有:800个产品可消费】当前仓库产品数量:0  
  14. 【仓库还未满,生产:200个产品没有问题】当前仓库产品数量:0  
  15. 【仓库没有:800个产品可消费】当前仓库产品数量:200  
  16. 【仓库还未满,生产:100个产品没有问题】当前仓库产品数量:200  
  17. 【仓库没有:800个产品可消费】当前仓库产品数量:300  
  18. 【仓库还未满,生产:400个产品没有问题】当前仓库产品数量:300  
  19. 【仓库没有:800个产品可消费】当前仓库产品数量:700  
  20. 【仓库已无法再生产:500个产品】当前仓库产品数量:700  
结果不一定会和我一样

二、lock实现

    lock的实现其实和上面差不多,只不过还引入了lock,newCondition的条件,这是一个类似wait/notify的东西,用法也差不多。代码如下:

[java]  view plain  copy
  1. package com.lin;  
  2.   
  3. import java.util.LinkedList;  
  4. import java.util.List;  
  5. import java.util.concurrent.locks.Condition;  
  6. import java.util.concurrent.locks.Lock;  
  7. import java.util.concurrent.locks.ReentrantLock;  
  8.   
  9. class Storehouse {  
  10.     // 仓库的容量  
  11.     private int capacity;  
  12.     // object当成是生产的商品  
  13.     private List<Object> list = new LinkedList<Object>();  
  14.   
  15.      // 锁    
  16.     private final Lock lock = new ReentrantLock();    
  17.     
  18.     // 仓库满的条件变量    
  19.     private final Condition full = lock.newCondition();    
  20.     
  21.     // 仓库空的条件变量    
  22.     private final Condition empty = lock.newCondition();    
  23.       
  24.     public Storehouse(int capacity) {  
  25.         this.capacity = capacity;  
  26.         System.out.println("当前仓库产品数量:" + list.size());  
  27.     }  
  28.   
  29.     public int getCapacity() {  
  30.         return capacity;  
  31.     }  
  32.   
  33.     public void setCapacity(int capacity) {  
  34.         this.capacity = capacity;  
  35.     }  
  36.   
  37.     /** 
  38.      * 生产的方法 
  39.      *  
  40.      * @throws InterruptedException 
  41.      */  
  42.     public void produrce(int num) throws InterruptedException {  
  43.         try {  
  44.             lock.lock();  
  45.             // 仓库还未满,且再生产num个产品不会超过仓库容量时可以生产产品  
  46.             while (list.size() + num > this.capacity) {  
  47.                 // 仓库已满,或者放不下  
  48.                System.out.println("【仓库已无法再生产:" + num + "个产品】" + "当前仓库产品数量:" + list.size());  
  49.                empty.await();   
  50.             }  
  51.             System.out.println("【仓库还未满,生产:" + num + "个产品没有问题】" + "当前仓库产品数量:" + list.size());  
  52.             for (int i = 0; i < num; i++) {  
  53.                 list.add(new Object());  
  54.             }  
  55.             full.signalAll();  
  56.             empty.signalAll();  
  57.         } finally {  
  58.             lock.unlock();  
  59.         }  
  60.     }  
  61.   
  62.     /** 
  63.      * 消费 
  64.      *  
  65.      * @param num 
  66.      * @throws InterruptedException 
  67.      */  
  68.     public void consumer(int num) throws InterruptedException {  
  69.         try {  
  70.             lock.lock();  
  71.             // 仓库有没有num个产品可消费  
  72.             while (list.size() < num) {  
  73.                 System.out.println("【仓库没有:" + num + "个产品可消费】" + "当前仓库产品数量:" + list.size());  
  74.                 full.await();  
  75.             }  
  76.             System.out.println("【仓库有:" + num + "个产品可消费】" + "当前仓库产品数量:" + list.size());  
  77.             for (int i = 0; i < num; i++) {  
  78.                 list.remove(0);  
  79.             }  
  80.             empty.signalAll();  
  81.             full.signalAll();  
  82.         } finally {  
  83.             lock.unlock();  
  84.         }  
  85.     }  
  86. }  
  87.   
  88.     class ProducerThread extends Thread {  
  89.         // 每次生产的产品数量  
  90.         private int num;  
  91.   
  92.         // 所在放置的仓库  
  93.         private Storehouse storehouse;  
  94.   
  95.         // 构造函数,设置仓库  
  96.         public ProducerThread(Storehouse storehouse, int num) {  
  97.             this.storehouse = storehouse;  
  98.             this.num = num;  
  99.         }  
  100.   
  101.         public void run() {  
  102.             try {  
  103.                 storehouse.produrce(num);  
  104.             } catch (InterruptedException e) {  
  105.                 e.printStackTrace();  
  106.             }  
  107.         }  
  108.     }  
  109.   
  110.     class ConsumerThread extends Thread {  
  111.         // 每次生产的产品数量  
  112.         private int num;  
  113.   
  114.         // 所在放置的仓库  
  115.         private Storehouse storehouse;  
  116.   
  117.         // 构造函数,设置仓库  
  118.         public ConsumerThread(Storehouse storehouse, int num) {  
  119.             this.storehouse = storehouse;  
  120.             this.num = num;  
  121.         }  
  122.   
  123.         public void run() {  
  124.             try {  
  125.                 storehouse.consumer(num);  
  126.             } catch (InterruptedException e) {  
  127.                 e.printStackTrace();  
  128.             }  
  129.         }  
  130.   
  131.     }  
  132.   
  133. public class Test2 {  
  134.   
  135.     public static void main(String[] args) {  
  136.   
  137.         // 仓库对象  
  138.         Storehouse storage = new Storehouse(1000);  
  139.   
  140.         // 生产者对象  
  141.         ProducerThread p1 = new ProducerThread(storage, 200);  
  142.         ProducerThread p2 = new ProducerThread(storage, 200);  
  143.         ProducerThread p3 = new ProducerThread(storage, 100);  
  144.         ProducerThread p4 = new ProducerThread(storage, 300);  
  145.         ProducerThread p5 = new ProducerThread(storage, 400);  
  146.         ProducerThread p6 = new ProducerThread(storage, 200);  
  147.         ProducerThread p7 = new ProducerThread(storage, 500);  
  148.   
  149.         // 消费者对象  
  150.         ConsumerThread c1 = new ConsumerThread(storage, 500);  
  151.         ConsumerThread c2 = new ConsumerThread(storage, 200);  
  152.         ConsumerThread c3 = new ConsumerThread(storage, 800);  
  153.   
  154.         // 线程开始执行  
  155.         c1.start();  
  156.         c2.start();  
  157.         c3.start();  
  158.         p1.start();  
  159.         p2.start();  
  160.         p3.start();  
  161.         p4.start();  
  162.         p5.start();  
  163.         p6.start();  
  164.         p7.start();  
  165.   
  166.     }  
  167.   
  168. }  
输出结果:

[plain]  view plain  copy
  1. 当前仓库产品数量:0  
  2. 【仓库没有:500个产品可消费】当前仓库产品数量:0  
  3. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  4. 【仓库还未满,生产:200个产品没有问题】当前仓库产品数量:0  
  5. 【仓库还未满,生产:100个产品没有问题】当前仓库产品数量:200  
  6. 【仓库还未满,生产:500个产品没有问题】当前仓库产品数量:300  
  7. 【仓库还未满,生产:200个产品没有问题】当前仓库产品数量:800  
  8. 【仓库已无法再生产:300个产品】当前仓库产品数量:1000  
  9. 【仓库已无法再生产:200个产品】当前仓库产品数量:1000  
  10. 【仓库有:500个产品可消费】当前仓库产品数量:1000  
  11. 【仓库有:200个产品可消费】当前仓库产品数量:500  
  12. 【仓库还未满,生产:400个产品没有问题】当前仓库产品数量:300  
  13. 【仓库没有:800个产品可消费】当前仓库产品数量:700  
  14. 【仓库还未满,生产:300个产品没有问题】当前仓库产品数量:700  
  15. 【仓库已无法再生产:200个产品】当前仓库产品数量:1000  
  16. 【仓库有:800个产品可消费】当前仓库产品数量:1000  
  17. 【仓库还未满,生产:200个产品没有问题】当前仓库产品数量:200  

三、BlockingQueue实现

BlockingQueue是阻塞队列,可以实现入队阻塞、取数阻塞。对于生产者-消费者很适用,而且可以实现一有产品就可以马上就进行消费。不用像上面的两种方法都等到仓库生产足够的产品后才进行消费。而且代码量也不多,容易理解,代码如下:

[java]  view plain  copy
  1. package com.lin;  
  2.   
  3. import java.util.concurrent.ArrayBlockingQueue;  
  4. import java.util.concurrent.BlockingQueue;  
  5. import java.util.concurrent.atomic.AtomicInteger;  
  6.   
  7. class Storehouse {  
  8.     // 仓库的容量  
  9.     private int capacity;  
  10.     // 仓库存储的载体  
  11.     private BlockingQueue<Object> blockingQueue;  
  12.     // 当前个数  
  13.     private AtomicInteger curNum = new AtomicInteger(0);  
  14.   
  15.     public Storehouse(int capacity) {  
  16.         this.capacity = capacity;  
  17.         this.blockingQueue = new ArrayBlockingQueue<Object>(capacity);  
  18.     }  
  19.   
  20.     /** 
  21.      * 生产的方法 
  22.      *  
  23.      * @throws InterruptedException 
  24.      */  
  25.     public void produrce(int num) {  
  26.         while (num + curNum.get() > capacity) {  
  27.             System.out.println("【仓库已无法再生产:" + num + "个产品】" + "当前仓库产品数量:" + curNum.get());  
  28.         }  
  29.   
  30.         System.out.println("【仓库还未满,生产:" + num + "个产品没有问题】" + "当前仓库产品数量:" + blockingQueue.size());  
  31.         for (int i = 0; i < num; i++) {  
  32.             blockingQueue.add(new Object());  
  33.             curNum.incrementAndGet();  
  34.         }  
  35.   
  36.     }  
  37.   
  38.     /** 
  39.      * 消费 
  40.      *  
  41.      * @param num 
  42.      * @throws InterruptedException 
  43.      */  
  44.     public void consumer(int num) {  
  45.         while (num > curNum.get()) {  
  46.             System.out.println("【仓库没有:" + num + "个产品可消费】" + "当前仓库产品数量:" + blockingQueue.size());  
  47.         }  
  48.   
  49.         System.out.println("【仓库有:" + num + "个产品可消费】" + "当前仓库产品数量:" + blockingQueue.size());  
  50.         for (int i = 0; i < num; i++) {  
  51.             try {  
  52.                 blockingQueue.take();  
  53.             } catch (InterruptedException e) {  
  54.                 e.printStackTrace();  
  55.             }  
  56.             curNum.decrementAndGet();  
  57.         }  
  58.   
  59.     }  
  60. }  
  61.   
  62. class ProducerThread extends Thread {  
  63.     // 每次生产的产品数量  
  64.     private int num;  
  65.   
  66.     // 所在放置的仓库  
  67.     private Storehouse storehouse;  
  68.   
  69.     // 构造函数,设置仓库  
  70.     public ProducerThread(Storehouse storehouse, int num) {  
  71.         this.storehouse = storehouse;  
  72.         this.num = num;  
  73.     }  
  74.   
  75.     public void run() {  
  76.             storehouse.produrce(num);  
  77.     }  
  78. }  
  79.   
  80. class ConsumerThread extends Thread {  
  81.     // 每次生产的产品数量  
  82.     private int num;  
  83.   
  84.     // 所在放置的仓库  
  85.     private Storehouse storehouse;  
  86.   
  87.     // 构造函数,设置仓库  
  88.     public ConsumerThread(Storehouse storehouse, int num) {  
  89.         this.storehouse = storehouse;  
  90.         this.num = num;  
  91.     }  
  92.   
  93.     public void run() {  
  94.             storehouse.consumer(num);  
  95.     }  
  96.   
  97. }  
  98.   
  99. public class Test3 {  
  100.   
  101.     public static void main(String[] args) {  
  102.         // 仓库对象  
  103.         Storehouse storage = new Storehouse(1000);  
  104.   
  105.         // 生产者对象  
  106.         ProducerThread p1 = new ProducerThread(storage, 200);  
  107.         ProducerThread p2 = new ProducerThread(storage, 200);  
  108.         ProducerThread p3 = new ProducerThread(storage, 100);  
  109.         ProducerThread p4 = new ProducerThread(storage, 300);  
  110.         ProducerThread p5 = new ProducerThread(storage, 400);  
  111.         ProducerThread p6 = new ProducerThread(storage, 200);  
  112.         ProducerThread p7 = new ProducerThread(storage, 500);  
  113.   
  114.         // 消费者对象  
  115.         ConsumerThread c1 = new ConsumerThread(storage, 500);  
  116.         ConsumerThread c2 = new ConsumerThread(storage, 200);  
  117.         ConsumerThread c3 = new ConsumerThread(storage, 800);  
  118.   
  119.         // 线程开始执行  
  120.         c1.start();  
  121.         c2.start();  
  122.         c3.start();  
  123.         p1.start();  
  124.         p2.start();  
  125.         p3.start();  
  126.         p4.start();  
  127.         p5.start();  
  128.         p6.start();  
  129.         p7.start();  
  130.   
  131.     }  
  132.   
  133. }  
输出结果:

[plain]  view plain  copy
  1. 【仓库没有:500个产品可消费】当前仓库产品数量:0  
  2. 【仓库没有:500个产品可消费】当前仓库产品数量:0  
  3. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  4. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  5. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  6. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  7. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  8. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  9. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  10. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  11. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  12. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  13. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  14. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  15. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  16. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  17. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  18. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  19. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  20. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  21. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  22. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  23. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  24. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  25. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  26. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  27. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  28. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  29. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  30. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  31. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  32. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  33. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  34. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  35. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  36. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  37. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  38. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  39. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  40. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  41. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  42. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  43. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  44. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  45. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  46. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  47. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  48. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  49. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  50. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  51. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  52. 【仓库还未满,生产:200个产品没有问题】当前仓库产品数量:0  
  53. 【仓库还未满,生产:200个产品没有问题】当前仓库产品数量:1  
  54. 【仓库没有:500个产品可消费】当前仓库产品数量:0  
  55. 【仓库没有:200个产品可消费】当前仓库产品数量:0  
  56. 【仓库没有:200个产品可消费】当前仓库产品数量:39  
  57. 【仓库还未满,生产:300个产品没有问题】当前仓库产品数量:39  
  58. 【仓库还未满,生产:100个产品没有问题】当前仓库产品数量:113  
  59. 【仓库没有:800个产品可消费】当前仓库产品数量:0  
  60. 【仓库还未满,生产:200个产品没有问题】当前仓库产品数量:165  
  61. 【仓库没有:200个产品可消费】当前仓库产品数量:39  
  62. 【仓库有:200个产品可消费】当前仓库产品数量:273  
  63. 【仓库没有:500个产品可消费】当前仓库产品数量:39  
  64. 【仓库没有:500个产品可消费】当前仓库产品数量:327  
  65. 【仓库没有:500个产品可消费】当前仓库产品数量:327  
  66. 【仓库没有:500个产品可消费】当前仓库产品数量:327  
  67. 【仓库还未满,生产:400个产品没有问题】当前仓库产品数量:327  
  68. 【仓库没有:800个产品可消费】当前仓库产品数量:327  
  69. 【仓库没有:500个产品可消费】当前仓库产品数量:327  
  70. 【仓库没有:800个产品可消费】当前仓库产品数量:479  
  71. 【仓库没有:800个产品可消费】当前仓库产品数量:497  
  72. 【仓库没有:500个产品可消费】当前仓库产品数量:516  
  73. 【仓库有:500个产品可消费】当前仓库产品数量:516  
  74. 【仓库还未满,生产:500个产品没有问题】当前仓库产品数量:506  
  75. 【仓库没有:800个产品可消费】当前仓库产品数量:558  
  76. 【仓库没有:800个产品可消费】当前仓库产品数量:558  
  77. 【仓库没有:800个产品可消费】当前仓库产品数量:558  
  78. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  79. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  80. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  81. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  82. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  83. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  84. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  85. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  86. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  87. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  88. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  89. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  90. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  91. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  92. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  93. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  94. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  95. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  96. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  97. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  98. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  99. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  100. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  101. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  102. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  103. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  104. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  105. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  106. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  107. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  108. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  109. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  110. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  111. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  112. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  113. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  114. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  115. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  116. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  117. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  118. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  119. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  120. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  121. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  122. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  123. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  124. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  125. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  126. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  127. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  128. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  129. 【仓库没有:800个产品可消费】当前仓库产品数量:568  
  130. 【仓库没有:800个产品可消费】当前仓库产品数量:567  
  131. 【仓库没有:800个产品可消费】当前仓库产品数量:557  
  132. 【仓库没有:800个产品可消费】当前仓库产品数量:607  
  133. 【仓库没有:800个产品可消费】当前仓库产品数量:710  
  134. 【仓库没有:800个产品可消费】当前仓库产品数量:727  
  135. 【仓库没有:800个产品可消费】当前仓库产品数量:719  
  136. 【仓库没有:800个产品可消费】当前仓库产品数量:719  
  137. 【仓库没有:800个产品可消费】当前仓库产品数量:760  
  138. 【仓库没有:800个产品可消费】当前仓库产品数量:760  
  139. 【仓库没有:800个产品可消费】当前仓库产品数量:760  
  140. 【仓库没有:800个产品可消费】当前仓库产品数量:760  
  141. 【仓库没有:800个产品可消费】当前仓库产品数量:760  
  142. 【仓库没有:800个产品可消费】当前仓库产品数量:760  
  143. 【仓库没有:800个产品可消费】当前仓库产品数量:760  
  144. 【仓库没有:800个产品可消费】当前仓库产品数量:760  
  145. 【仓库没有:800个产品可消费】当前仓库产品数量:760  
  146. 【仓库没有:800个产品可消费】当前仓库产品数量:760  
  147. 【仓库没有:800个产品可消费】当前仓库产品数量:760  
  148. 【仓库没有:800个产品可消费】当前仓库产品数量:769  
  149. 【仓库有:800个产品可消费】当前仓库产品数量:835  

猜你喜欢

转载自blog.csdn.net/j_cong/article/details/78624216