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

首先声明,本人只是为了巩固知识而写博客,如果你看了这篇博客对你有帮助,那么我很开心,如果没有帮助,那我也很遗憾,如果有错误很高兴你指出来,只希望不要骂人,谢谢。

什么是生产者和消费者

首先,我们都学过生物,顾名思义可以知道,生产者就是负责生产东西的,
消费者就是用来消费东西的。

生产者和消费者有什么用

打个比方,我们去肯德基或者麦当劳点餐,那么我们就是线程里面的“消费者”,而那些负责制作食物的员工就是“生产者”
当我们点餐完成后,负责生产食物的人员不是去生产食物了,而是把之前生产好的食物搬到你的面前,然后你在开始进行用餐。
如果负责生产食物的人员发现食物的存储量已经低于一个值,那么这个时候,负责生产食物的人员就要开始去生产食物了,与此同时,消费者也要停止进餐,开始休息。

什么是缓冲区

这个很容易理解就相当于装食物的容器,我们去肯德基麦当劳点餐的时候,是不是会看见有一个大大的容器,里面就是装食物的,当我们把食物消灭到一定数量的时候,工作人员又开始继续制作食物了。

看图理解

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

代码实现(容器)

class RQ //定义一个容器类
{
    Egg[] eggs=new Egg[10];  //new一个鸡蛋数组就十个吧,鸡蛋类会在下面写到
    int count =1; //一开始有一个鸡蛋
    public synchronized void push(Egg egg ) throws InterruptedException {
        if(count==eggs.length) {
            this.wait();//如果鸡蛋的数量等于数组的长度,也就是十,线程开始等待,这个时候下面的代码不会执行
        }
        //当这个线程被唤醒,开始执行
        eggs[count]=egg;//
        count++;
        this.notifyAll();

    }

    public synchronized Egg pop() throws InterruptedException {
        if(count==1)
        {
            this.wait();//如果鸡蛋只有一个,那么线程开始等待
        }
        //线程被唤醒后开始执行
        count--;
        Egg egg=eggs[count];
        this.notifyAll();
        return egg;
    }

}


代码实现(生产者)

class scz implements Runnable
{
    RQ rq =new RQ();//先new一个容器
    public scz(RQ rq) {
        this.rq = rq;
    }

    @Override
    public void run() {
        for (int i = 1; i <= 10; i++) {
             System.out.println("生产了第--->"+i+"个鸡蛋");
            try {
                rq.push(new Egg(i));//没生产一个鸡蛋,就调用rq函数的push,并且把i传入到Egg的id里面;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }

    }
}

代码实现(消费者)

class xfz implements Runnable
{
    RQ rq =new RQ();//new一个容器
    public xfz(RQ rq) {
        this.rq = rq;
    }

    @Override
    public void run() {
        for (int i = 1; i <= 10; i++) {
            try {
                System.out.println("消费了第--->"+rq.pop().id+"个鸡蛋");
                //如果是写i的话那么消费者吃掉的鸡蛋就和生产者生产的数量没关系
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}

代码实现(鸡蛋)

class Egg
{
    int id=0;

    public Egg(int id) {
        this.id = id;
    }
}

全部代码总和

package Thread;

public class mytest01 {
    public static void main(String[] args) {
        RQ rq=new RQ();
        scz s=new scz(rq);
        xfz x =new xfz(rq);
        Thread t1=new Thread(s);
        Thread t2=new Thread(x);
        t1.start();
        t2.start();

    }
}
class scz implements Runnable
{
    RQ rq =new RQ();

    public scz(RQ rq) {
        this.rq = rq;
    }

    @Override
    public void run() {
        for (int i = 1; i <= 10; i++) {
             System.out.println("生产了第--->"+i+"个鸡蛋");
            try {
                rq.push(new Egg(i));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }

    }
}

class xfz implements Runnable
{
    RQ rq =new RQ();
    public xfz(RQ rq) {
        this.rq = rq;
    }

    @Override
    public void run() {
        for (int i = 1; i <= 10; i++) {
            try {
                System.out.println("消费了第--->"+rq.pop().id+"个鸡蛋");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}

class RQ
{
    Egg[] eggs=new Egg[10];
    int count =1;
    public synchronized void push(Egg egg ) throws InterruptedException {
        if(count==eggs.length) {
            this.wait();
        }
        eggs[count]=egg;
        count++;
        this.notifyAll();

    }

    public synchronized Egg pop() throws InterruptedException {
        if(count==1)
        {
            this.wait();
        }
        count--;
        Egg egg=eggs[count];

        this.notifyAll();
        return egg;
    }

}

class Egg
{
    int id=0;

    public Egg(int id) {
        this.id = id;
    }
}

结果

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

每一次运行结果都会是不一样的,因为每次cpu调度的时间不一样,结果就不一样,同时,消费者不会按照生产者生产的顺序吃食物,是拿起来就是随便吃,可能先吃第四个的时候,生产者下一波食物就生成了,他就直接吃了下一波的食物。

总结

总的来说,只需要控制好变量,这个并不是很难理解,但是要锁对地方,如果锁错地方那么就会出现错误的结果,这个是我第一次写博客,写的不好还请见谅,希望可以帮助到你。

上一篇:虚拟机 网络不可达 连不上网 Destination Host Unreachable


下一篇:ping 外网 icmp_seq=1 Destination Host Unreachable