1.实现方式1:wait() / notify()方法
源代码:
package com.sunny.www.multiThreads.producerAndConsumer.byWaitNotify; import java.util.LinkedList; /** * 实现方式1:wait() / notify()方法 * @author zy */ public class ByWaitNotify { public static void main(String[] args) { // 仓库对象 Storage storage = new Storage(); for(int i = 1; i <= 20; i++){ Producer producer = new Producer(storage); producer.setNum(30); producer.start(); } for(int i = 1; i <= 30; i++){ Consumer consumer = new Consumer(storage); consumer.setNum(20); consumer.start(); } } } /** * 仓库类 */ class Storage { // 仓库最大存储量 private final int MAX_SIZE = 200; // 仓库存储的载体 private LinkedList<Object> list = new LinkedList<Object>(); //生产N个产品 public void produce(int num){ synchronized (list) { while(list.size() + num > MAX_SIZE){ System.out.println("【要生产的产品数量】:" + num + "/t【库存量】:" + list.size() + "/t暂时不能执行生产任务!"); try { // 由于条件不满足,生产阻塞 list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 生产条件满足情况下,生产num个产品 for (int i = 1; i <= num; ++i) { list.add(new Object()); try { Thread.sleep((int) Math.random() * 10); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("【已经生产产品数】:" + num + "/t【现仓储量为】:" + list.size()); list.notifyAll(); } } // 消费num个产品 public void consume(int num) { // 同步代码段 synchronized (list) { // 如果仓库存储量不足 while (list.size() < num) { System.out.println("【要消费的产品数量】:" + num + "/t【库存量】:" + list.size() + "/t暂时不能执行消费任务!"); try { // 由于条件不满足,消费阻塞 list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 消费条件满足情况下,消费num个产品 for (int i = 1; i <= num; ++i) { list.remove(); try { Thread.sleep((int) Math.random() * 10); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("【已经消费产品数】:" + num + "/t【现仓储量为】:" + list.size()); list.notifyAll(); } } public LinkedList<Object> getList() { return list; } public void setList(LinkedList<Object> list) { this.list = list; } public int getMAX_SIZE() { return MAX_SIZE; } } class Producer extends Thread { // 每次生产的产品数量 private int num; // 所在放置的仓库 private Storage storage; // 构造函数,设置仓库 public Producer(Storage storage) { this.storage = storage; } // 线程run函数 @Override public void run() { produce(num); } // 调用仓库Storage的生产函数 public void produce(int num) { storage.produce(num); } // get/set方法 public int getNum() { return num; } public void setNum(int num) { this.num = num; } public Storage getStorage() { return storage; } public void setStorage(Storage storage) { this.storage = storage; } } class Consumer extends Thread { // 每次消费的产品数量 private int num; // 所在放置的仓库 private Storage storage; // 构造函数,设置仓库 public Consumer(Storage storage) { this.storage = storage; } // 线程run函数 @Override public void run() { consume(num); } // 调用仓库Storage的生产函数 public void consume(int num) { storage.consume(num); } // get/set方法 public int getNum() { return num; } public void setNum(int num) { this.num = num; } public Storage getStorage() { return storage; } public void setStorage(Storage storage) { this.storage = storage; } }
运行效果:

【已经生产产品数】:30/t【现仓储量为】:30 【已经生产产品数】:30/t【现仓储量为】:60 【已经生产产品数】:30/t【现仓储量为】:90 【已经生产产品数】:30/t【现仓储量为】:120 【已经生产产品数】:30/t【现仓储量为】:150 【已经生产产品数】:30/t【现仓储量为】:180 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【已经消费产品数】:20/t【现仓储量为】:160 【已经生产产品数】:30/t【现仓储量为】:190 【已经消费产品数】:20/t【现仓储量为】:170 【已经生产产品数】:30/t【现仓储量为】:200 【要生产的产品数量】:30/t【库存量】:200/t暂时不能执行生产任务! 【已经消费产品数】:20/t【现仓储量为】:180 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【已经消费产品数】:20/t【现仓储量为】:160 【已经生产产品数】:30/t【现仓储量为】:190 【要生产的产品数量】:30/t【库存量】:190/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:190/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:190/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:190/t暂时不能执行生产任务! 【已经消费产品数】:20/t【现仓储量为】:170 【已经生产产品数】:30/t【现仓储量为】:200 【要生产的产品数量】:30/t【库存量】:200/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:200/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:200/t暂时不能执行生产任务! 【已经消费产品数】:20/t【现仓储量为】:180 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【已经消费产品数】:20/t【现仓储量为】:160 【已经消费产品数】:20/t【现仓储量为】:140 【已经消费产品数】:20/t【现仓储量为】:120 【已经消费产品数】:20/t【现仓储量为】:100 【已经消费产品数】:20/t【现仓储量为】:80 【已经生产产品数】:30/t【现仓储量为】:110 【已经生产产品数】:30/t【现仓储量为】:140 【已经生产产品数】:30/t【现仓储量为】:170 【已经生产产品数】:30/t【现仓储量为】:200 【已经消费产品数】:20/t【现仓储量为】:180 【已经消费产品数】:20/t【现仓储量为】:160 【已经消费产品数】:20/t【现仓储量为】:140 【已经生产产品数】:30/t【现仓储量为】:170 【已经生产产品数】:30/t【现仓储量为】:200 【已经消费产品数】:20/t【现仓储量为】:180 【已经消费产品数】:20/t【现仓储量为】:160 【已经生产产品数】:30/t【现仓储量为】:190 【已经消费产品数】:20/t【现仓储量为】:170 【已经消费产品数】:20/t【现仓储量为】:150 【已经消费产品数】:20/t【现仓储量为】:130 【已经消费产品数】:20/t【现仓储量为】:110 【已经消费产品数】:20/t【现仓储量为】:90 【已经消费产品数】:20/t【现仓储量为】:70 【已经消费产品数】:20/t【现仓储量为】:50 【已经消费产品数】:20/t【现仓储量为】:30 【已经消费产品数】:20/t【现仓储量为】:10 【要消费的产品数量】:20/t【库存量】:10/t暂时不能执行消费任务! 【要消费的产品数量】:20/t【库存量】:10/t暂时不能执行消费任务! 【已经生产产品数】:30/t【现仓储量为】:40 【已经生产产品数】:30/t【现仓储量为】:70 【已经生产产品数】:30/t【现仓储量为】:100 【已经消费产品数】:20/t【现仓储量为】:80 【已经消费产品数】:20/t【现仓储量为】:60 【已经消费产品数】:20/t【现仓储量为】:40 【已经消费产品数】:20/t【现仓储量为】:20 【已经消费产品数】:20/t【现仓储量为】:0
2.实现方式2:await() / signal()方法
源代码:
package com.sunny.www.multiThreads.producerAndConsumer.byAwaitSignal; import java.util.LinkedList; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * 实现方式2:await() / signal()方法 * @author zy */ public class ByAwaitSignal { /** * @param args */ public static void main(String[] args) { // 仓库对象 Storage storage = new Storage(); for(int i = 1; i <= 20; i++){ Producer producer = new Producer(storage); producer.setNum(30); producer.start(); } for(int i = 1; i <= 30; i++){ Consumer consumer = new Consumer(storage); consumer.setNum(20); consumer.start(); } } } class Storage { // 仓库最大存储量 private final int MAX_SIZE = 200; // 仓库存储的载体 private LinkedList<Object> list = new LinkedList<Object>(); // 锁 private final Lock lock = new ReentrantLock(); // 仓库满的条件变量 private final Condition full = lock.newCondition(); // 仓库空的条件变量 private final Condition empty = lock.newCondition(); // 生产num个产品 public void produce(int num) { // 获得锁 lock.lock(); // 如果仓库剩余容量不足 while (list.size() + num > MAX_SIZE) { System.out.println("【要生产的产品数量】:" + num + "/t【库存量】:" + list.size() + "/t暂时不能执行生产任务!"); try { // 由于条件不满足,生产阻塞 full.await(); } catch (InterruptedException e) { e.printStackTrace(); } } // 生产条件满足情况下,生产num个产品 for (int i = 1; i <= num; ++i) { list.add(new Object()); } System.out.println("【已经生产产品数】:" + num + "/t【现仓储量为】:" + list.size()); // 唤醒其他所有线程 full.signalAll(); empty.signalAll(); // 释放锁 lock.unlock(); } // 消费num个产品 public void consume(int num) { // 获得锁 lock.lock(); // 如果仓库存储量不足 while (list.size() < num) { System.out.println("【要消费的产品数量】:" + num + "/t【库存量】:" + list.size() + "/t暂时不能执行消费任务!"); try { // 由于条件不满足,消费阻塞 empty.await(); } catch (InterruptedException e) { e.printStackTrace(); } } // 消费条件满足情况下,消费num个产品 for (int i = 1; i <= num; ++i) { list.remove(); } System.out.println("【已经消费产品数】:" + num + "/t【现仓储量为】:" + list.size()); // 唤醒其他所有线程 full.signalAll(); empty.signalAll(); // 释放锁 lock.unlock(); } // set/get方法 public int getMAX_SIZE() { return MAX_SIZE; } public LinkedList<Object> getList() { return list; } public void setList(LinkedList<Object> list) { this.list = list; } } class Producer extends Thread { // 每次生产的产品数量 private int num; // 所在放置的仓库 private Storage storage; // 构造函数,设置仓库 public Producer(Storage storage) { this.storage = storage; } // 线程run函数 @Override public void run() { produce(num); } // 调用仓库Storage的生产函数 public void produce(int num) { storage.produce(num); } // get/set方法 public int getNum() { return num; } public void setNum(int num) { this.num = num; } public Storage getStorage() { return storage; } public void setStorage(Storage storage) { this.storage = storage; } } class Consumer extends Thread { // 每次消费的产品数量 private int num; // 所在放置的仓库 private Storage storage; // 构造函数,设置仓库 public Consumer(Storage storage) { this.storage = storage; } // 线程run函数 @Override public void run() { consume(num); } // 调用仓库Storage的生产函数 public void consume(int num) { storage.consume(num); } // get/set方法 public int getNum() { return num; } public void setNum(int num) { this.num = num; } public Storage getStorage() { return storage; } public void setStorage(Storage storage) { this.storage = storage; } }
运行效果:

【已经生产产品数】:30/t【现仓储量为】:30 【已经生产产品数】:30/t【现仓储量为】:60 【已经生产产品数】:30/t【现仓储量为】:90 【已经生产产品数】:30/t【现仓储量为】:120 【已经生产产品数】:30/t【现仓储量为】:150 【已经生产产品数】:30/t【现仓储量为】:180 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【已经消费产品数】:20/t【现仓储量为】:160 【已经生产产品数】:30/t【现仓储量为】:190 【已经消费产品数】:20/t【现仓储量为】:170 【已经消费产品数】:20/t【现仓储量为】:150 【已经消费产品数】:20/t【现仓储量为】:130 【已经消费产品数】:20/t【现仓储量为】:110 【已经消费产品数】:20/t【现仓储量为】:90 【已经消费产品数】:20/t【现仓储量为】:70 【已经消费产品数】:20/t【现仓储量为】:50 【已经生产产品数】:30/t【现仓储量为】:80 【已经消费产品数】:20/t【现仓储量为】:60 【已经生产产品数】:30/t【现仓储量为】:90 【已经生产产品数】:30/t【现仓储量为】:120 【已经生产产品数】:30/t【现仓储量为】:150 【已经生产产品数】:30/t【现仓储量为】:180 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【要生产的产品数量】:30/t【库存量】:180/t暂时不能执行生产任务! 【已经消费产品数】:20/t【现仓储量为】:160 【已经消费产品数】:20/t【现仓储量为】:140 【已经消费产品数】:20/t【现仓储量为】:120 【已经消费产品数】:20/t【现仓储量为】:100 【已经消费产品数】:20/t【现仓储量为】:80 【已经消费产品数】:20/t【现仓储量为】:60 【已经消费产品数】:20/t【现仓储量为】:40 【已经消费产品数】:20/t【现仓储量为】:20 【已经消费产品数】:20/t【现仓储量为】:0 【要消费的产品数量】:20/t【库存量】:0/t暂时不能执行消费任务! 【已经生产产品数】:30/t【现仓储量为】:30 【已经消费产品数】:20/t【现仓储量为】:10 【已经生产产品数】:30/t【现仓储量为】:40 【已经生产产品数】:30/t【现仓储量为】:70 【已经生产产品数】:30/t【现仓储量为】:100 【已经消费产品数】:20/t【现仓储量为】:80 【已经生产产品数】:30/t【现仓储量为】:110 【已经消费产品数】:20/t【现仓储量为】:90 【已经消费产品数】:20/t【现仓储量为】:70 【已经消费产品数】:20/t【现仓储量为】:50 【已经消费产品数】:20/t【现仓储量为】:30 【已经消费产品数】:20/t【现仓储量为】:10 【要消费的产品数量】:20/t【库存量】:10/t暂时不能执行消费任务! 【要消费的产品数量】:20/t【库存量】:10/t暂时不能执行消费任务! 【已经生产产品数】:30/t【现仓储量为】:40 【已经生产产品数】:30/t【现仓储量为】:70 【已经生产产品数】:30/t【现仓储量为】:100 【已经消费产品数】:20/t【现仓储量为】:80 【已经消费产品数】:20/t【现仓储量为】:60 【已经消费产品数】:20/t【现仓储量为】:40 【已经消费产品数】:20/t【现仓储量为】:20 【已经消费产品数】:20/t【现仓储量为】:0
3.实现方式3:BlockingQueue阻塞队列方法
源代码:
/** * */ package com.sunny.www.multiThreads.producerAndConsumer.byBlockingQueue; import java.util.concurrent.LinkedBlockingQueue; /** * 实现方式3:BlockingQueue阻塞队列方法 * @author zy * */ public class ByBlockingQueue { public static void main(String[] args) { // 仓库对象 Storage storage = new Storage(); for(int i = 1; i <= 30; i++){ Producer producer = new Producer(storage); producer.setNum(20); producer.start(); } for(int i = 1; i <= 20; i++){ Consumer consumer = new Consumer(storage); consumer.setNum(30); consumer.start(); } } } class Storage { // 仓库最大存储量 private final int MAX_SIZE = 200; // 仓库存储的载体 private LinkedBlockingQueue<Object> list = new LinkedBlockingQueue<Object>( 100); // 生产num个产品 public void produce(int num) { // 生产条件满足情况下,生产num个产品 for (int i = 1; i <= num; ++i) { // 如果仓库剩余容量为0 if (list.size() == MAX_SIZE) { System.out.println("【库存量】:" + MAX_SIZE + "/t暂时不能执行生产任务!"); return ; } try { // 放入产品,自动阻塞 list.put(new Object()); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("【现仓储量为】:" + list.size()); } // 消费num个产品 public void consume(int num) { // 消费条件满足情况下,消费num个产品 for (int i = 1; i <= num; ++i) { // 如果仓库存储量不足 if (list.size() == 0) { System.out.println("【库存量】:0/t暂时不能执行消费任务!"); return ; } try { // 消费产品,自动阻塞 list.take(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("【现仓储量为】:" + list.size()); } // set/get方法 public LinkedBlockingQueue<Object> getList() { return list; } public void setList(LinkedBlockingQueue<Object> list) { this.list = list; } public int getMAX_SIZE() { return MAX_SIZE; } } class Producer extends Thread { // 每次生产的产品数量 private int num; // 所在放置的仓库 private Storage storage; // 构造函数,设置仓库 public Producer(Storage storage) { this.storage = storage; } // 线程run函数 @Override public void run() { produce(num); } // 调用仓库Storage的生产函数 public void produce(int num) { storage.produce(num); } // get/set方法 public int getNum() { return num; } public void setNum(int num) { this.num = num; } public Storage getStorage() { return storage; } public void setStorage(Storage storage) { this.storage = storage; } } class Consumer extends Thread { // 每次消费的产品数量 private int num; // 所在放置的仓库 private Storage storage; // 构造函数,设置仓库 public Consumer(Storage storage) { this.storage = storage; } // 线程run函数 @Override public void run() { consume(num); } // 调用仓库Storage的生产函数 public void consume(int num) { storage.consume(num); } // get/set方法 public int getNum() { return num; } public void setNum(int num) { this.num = num; } public Storage getStorage() { return storage; } public void setStorage(Storage storage) { this.storage = storage; } }
运行效果:

【现仓储量为】:27 【现仓储量为】:43 【现仓储量为】:63 【现仓储量为】:81 【现仓储量为】:70 【现仓储量为】:54 【现仓储量为】:43 【现仓储量为】:71 【现仓储量为】:40 【现仓储量为】:11 【库存量】:0/t暂时不能执行消费任务! 【库存量】:0/t暂时不能执行消费任务! 【库存量】:0/t暂时不能执行消费任务! 【库存量】:0/t暂时不能执行消费任务! 【库存量】:0/t暂时不能执行消费任务! 【库存量】:0/t暂时不能执行消费任务! 【库存量】:0/t暂时不能执行消费任务! 【库存量】:0/t暂时不能执行消费任务! 【库存量】:0/t暂时不能执行消费任务! 【库存量】:0/t暂时不能执行消费任务! 【库存量】:0/t暂时不能执行消费任务! 【库存量】:0/t暂时不能执行消费任务! 【库存量】:0/t暂时不能执行消费任务! 【库存量】:0/t暂时不能执行消费任务! 【现仓储量为】:7 【库存量】:0/t暂时不能执行消费任务! 【现仓储量为】:12 【库存量】:0/t暂时不能执行消费任务! 【现仓储量为】:11 【现仓储量为】:19 【现仓储量为】:39 【现仓储量为】:89