生产者和消费者问题:管程法

管程法是用于解决线程之间通信与线程不安全的一种解决办法,典型的生产者与消费者问题可以通过管程法进行解决,特点是建立一个消费者和生产者发生通信的缓冲区,进而实现解决线程通信

实现思路:

  1. 创建四个类,分别用于定义消费者、生产者、产品、缓存区,四个类都有各自负责的事情
  2. Productor类需要实现生产产品,通过Store store定义一个store类型的数据,通过for循环模拟产品生产,再创建一个productor对象,通过store.push方法把产品编号传进去
  3. Consumer类负责消费产品,它也需要一个仓库对象store,因为它需要消费,所以for循环每执行一次产品数量-1
  4. product类实现的是生产的产品,给这个产品一个标记
  5. store是生产者和消费者之间连接的桥梁,相当于肯德基的前台,它需要负责的东西很多,首先要负责沟通后厨,如果生产的产品大于十个就让生产者停止生产,使用wait()方法,如果没有产品,就唤醒生产者继续生产,通过notifyall()方法唤醒生产者,还要有一个储物柜用于储存生产好的商品
import static jdk.nashorn.internal.objects.NativeArray.push;

public class TestPC {
    public static void main(String[] args) {
        Store store=new Store(); //创建一个仓库对象
        Productor productor = new Productor(store); //创建一个生产者对象并获取仓库对象
        Consumer consumer = new Consumer(store);    //创建一个消费者对象并获取仓库对象
        new Thread(productor).start();//线程进入就绪状态
        new Thread(consumer).start(); //线程就绪就绪状态
    }
}
//生产者
class Productor implements Runnable{
    Store store;       //生产者需要获取仓库对象用以存储产品
    Productor(Store store){
        this.store=store;
    }
    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            //将生产产品存入仓库
            Product product=new Product(i);
            store.push(product);
        }
    }
}
//消费者
class Consumer implements Runnable{
    Store store;
    Consumer(Store store){
        this.store=store;
    }
    @Override
    public void run() {
        for (int i = 1; i <= 100; i++){
            //取出一个产品
            store.pop();
        }
    }
}

//产品
class Product{
    //给产品一个id属性
    int id;
    public Product(int id){
        this.id=id;
    }

}
//仓库缓存区
class Store{
    Product []products=new Product[10];//定义一个容纳10个产品的对象数组
    static int count=0;//仓库产品数量计数,初始为0
    public synchronized void push(Product product){
        //判断仓库是否已满,若满则调用wait()方法令线程停止,使生产者停止产品的生产
        if (count>=10)
        {
            try {
                wait();//线程等待
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        products[count]=product;
        count++;
        System.out.println("生产者生产了第"+product.id+"个产品");
        this.notifyAll();//唤醒所有线程
    }
    public synchronized void pop(){
        //判断仓库是否存在产品,若无则调用wait()方法令线程停止,使消费者停止产品的获取
        if (count==0){
            try {
                wait();//线程等待
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        count--;
        Product product=products[count];
        System.out.println("消费者消费了第"+product.id+"个产品");
        this.notifyAll();//唤醒所有线程
    }


}
 

https://blog.csdn.net/weixin_45264992/article/details/115142206?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164966092016782092936630%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164966092016782092936630&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-2-115142206.142v7pc_search_result_cache,157v4control&utm_term=java%E7%AE%A1%E7%A8%8B%E6%B3%95&spm=1018.2226.3001.4187

posted @   萧何i  阅读(543)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示