生产消费模型
文章目录
前言
前面在学习线程的时候已经学习过了线程的6种状态:
- New:新建状态–使用new创建一个新的线程或其子类时线程的状态。
- Runnable:运行状态–多个线程抢占cpu资源的时候抢到资源的那个线程所处的状态。
- Blocked:阻塞状态–多个线程抢占cpu资源的时候未资源的线程所处的状态,在cpu空闲的时候会占用cpu变为Runnable状态。
- Terminated:死亡状态–run方法执行结束或者调用了stop方法的线程所处的状态。
- Timed_Waiting:休眠状态–调用了含有参数的wait或者sleep方法的线程所处的状态,在时间结束后如果cpu空闲会变成runnable状态,cpu不空闲会变成阻塞状态。可以自己被唤醒。
- Waiting:无限等待状态–调用了无参wait方法的线程所处的状态,会一直等待被唤醒。通过notify方法被唤醒。不可自己被唤醒。
在waiting状态和被唤醒状态之间切换有一个线程之间的通信模型叫生产-消费者模型,本文章代码实现一个生产消费者模型。
一、生产消费者模型
假设有这样三个部分,生产者,仓库,消费者。如果仓库没有产品消费者唤醒生产者,告诉生产者需要生产产品,唤醒生产者模型然后放弃cpu执行权进入wait状态等待被唤醒。生产者在接受到生产通知以后被唤醒,生产产品,然后唤醒消费者使用产品,如果产品数量达到了仓库容量上限,生产者会进入wait状态等待被唤醒。
注意wait和notify方法应该由同一个对象来调用,这里选择仓库对象来调用。
二、代码实现
生产者模型:
public class Producer implements Runnable {
private final ArrayList<Integer> warehouse;
private final int maxSize;
public Producer(ArrayList<Integer> warehouse, int maxSize) {
this.warehouse = warehouse;
this.maxSize = maxSize;
}
@Override
public void run() {
while (true) {
synchronized (warehouse) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (warehouse.size() > maxSize-1) {
try {
System.out.println("仓库中有"+warehouse.size()+"件产品,生产者模型进入wait");
warehouse.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("开始生产");
}else{
warehouse.add(warehouse.size()+1);
System.out.println("生产了第"+warehouse.size()+"个产品");
warehouse.notify();
// System.out.println("唤醒消费者开始消耗产品");
}
}
}
}
}
消费者模型:
public class Customer implements Runnable{
private final ArrayList<Integer> warehouse;
public Customer(ArrayList<Integer> warehouse) {
this.warehouse = warehouse;
}
@Override
public void run() {
while (true) {
synchronized (warehouse) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (warehouse.size() <=0) {
warehouse.notify();
System.out.println("告诉生产者开始生产");
try {
System.out.println();
System.out.println("消费者进入wait ");
warehouse.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
System.out.println(warehouse.size());
int re=warehouse.remove(warehouse.size()-1);
System.out.println("消费者消费了第"+re+"件产品");
}
}
}
}
}
主程序:
public class Manage {
//创建仓库对象
public static ArrayList<Integer> warehouse=new ArrayList<>();
public static int maxSize=20;
public static void main(String[] args) {
Producer producer=new Producer(warehouse, maxSize);
Customer customer=new Customer(warehouse);
Thread producerThread=new Thread(producer);
producerThread.start();
Thread customerThread=new Thread(customer);
customerThread.start();
}
}
以上代码经过测试可以成功的实现生产消费模型。