根据上图,可以分析出需求:
- 生产者和消费者共享一个缓存区,缓存区的最大容量为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 + "号";
}
@Override
public 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 + "号";
}
@Override
public 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
@NoArgsConstructor
public 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();
}
}
}
测试结果:
会发现中间有一段很奇怪: