生产消费模型

生产消费模型

文章目录

前言

前面在学习线程的时候已经学习过了线程的6种状态:

  1. New:新建状态–使用new创建一个新的线程或其子类时线程的状态。
  2. Runnable:运行状态–多个线程抢占cpu资源的时候抢到资源的那个线程所处的状态。
  3. Blocked:阻塞状态–多个线程抢占cpu资源的时候未资源的线程所处的状态,在cpu空闲的时候会占用cpu变为Runnable状态。
  4. Terminated:死亡状态–run方法执行结束或者调用了stop方法的线程所处的状态。
  5. Timed_Waiting:休眠状态–调用了含有参数的wait或者sleep方法的线程所处的状态,在时间结束后如果cpu空闲会变成runnable状态,cpu不空闲会变成阻塞状态。可以自己被唤醒。
  6. 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();
    }


}

以上代码经过测试可以成功的实现生产消费模型。

上一篇:预科第一天


下一篇:CrackMe01