
根据上图,可以分析出需求:
- 生产者和消费者共享一个缓存区,缓存区的最大容量为N
 - 生产者负责生产产品,并放入缓存区中;消费者负责消费产品,从缓存区中取出产品
 - 当缓存区满的时候,不能再放入缓存区,生产者需要阻塞等待
 - 当缓存区为空的时候,不能再取出产品,消费者要阻塞等待
 - 生产者和消费者进程对缓存区的访问是互斥的
 
使用Java代码,创建线程并使用锁完成上述需求:
/*** Created By IntelliJ IDEA** @author IceCreamQAQ* @datetime 2022/10/20 星期四* Happy Every Coding Time~*/public class Producer extends Thread{public static final Log log = LogFactory.get(Producer.class);private final MyData myData;private String name;public Producer(MyData myData, String name) {this.myData = myData;this.name = "生产者" + name + "号";}@Overridepublic void run() {while(true) {synchronized (myData) {log.info(this.name + "获取到锁");if(myData.getCount() == myData.getMaxNum()) {// 获取当前时间log.info(this.name + "已达到最大值,等待消费");try {myData.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}myData.setCount(myData.getCount() + 1);log.info(this.name + "生产一个产品,当前产品个数:" + myData.getCount());if(myData.getCount() == 1) {myData.notify();}try {Thread.sleep(500);} catch (InterruptedException e) {throw new RuntimeException(e);}}}}}
/*** Created By IntelliJ IDEA** @author IceCreamQAQ* @datetime 2022/10/20 星期四* Happy Every Coding Time~*/public class Consumer extends Thread{public static final Log log = LogFactory.get(Consumer.class);private final MyData myData;private String name;public Consumer(MyData myData, String name) {this.myData = myData;this.name = "消费者" + name + "号";}@Overridepublic void run() {while(true) {synchronized (myData) {log.info(this.name + "获取到锁");if (myData.getCount() == 0) {log.info(this.name + "已经消费完毕,等待生产");try {myData.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}myData.setCount(myData.getCount() - 1);log.info(this.name + "消费一个产品,当前产品个数:" + myData.getCount());if(myData.getCount() == myData.getMaxNum() - 1) {myData.notify();}try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}}}
/*** Created By IntelliJ IDEA** @author IceCreamQAQ* @datetime 2022/10/20 星期四* Happy Every Coding Time~*/@Data@AllArgsConstructor@NoArgsConstructorpublic class MyData {private int maxNum;private int count;}
/*** Created By IntelliJ IDEA** @author IceCreamQAQ* @datetime 2022/10/20 星期四* Happy Every Coding Time~*/public class Main {public static void main(String[] args) {int maxNum = 10;int count = 0;MyData myData = new MyData(maxNum, count);for(int i = 1;i <= 10;i++) {Producer producer = new Producer(myData, i + "");producer.start();}for(int i = 1;i <= 10;i++) {Consumer consumer = new Consumer(myData, i + "");consumer.start();}}}
测试结果:
会发现中间有一段很奇怪:
