线程生产消费者模型

生产消费者模型
1.在模型中,负责生产数据的模块是生产者,使用数据的是消费者
需要的是现有生产者去生产数据,然后才能有消费者去消费数据。
没有数据时候需要等待,消费者需要进行等待。
同时生产者,也需要等待消费者消费完了产品再进行生产。

1.首先写共享数据的那个类
这就是作为共享数据的类,用这个类的同一个对象作为锁锁住数据

package org.example.testjul;

public class ValueOf {
    private String value = "";

    public void setValue(){
        synchronized (this){
            if(!value.equals("")){
                //如果value不是是空串,那么就等待,毕竟为空时候加值才有意义
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            StringBuffer sb = new StringBuffer();
            sb.append(System.currentTimeMillis());
            sb.append("->");
            sb.append(System.nanoTime());
            System.out.println("设置的值就是i" + sb.toString());
            this.value = sb.toString();
            this.notify();//有可能是沉睡的,所以我们需要进行唤醒服务
        }
    }

    public void getValue(){
        //获得这个字段值
        synchronized (this){
            //还是用同一个对象作为锁
            if(this.value.equals("")){
                //当value是空的的时候
                //获取不到任何东西
                try {
                    this.wait();//让这时候来调用的线程进入等待状态
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }


            }

            //如果不是空那么线程直接获取到数值
            System.out.println("获取到数据是" + this.value);
            this.value = "";//设置为空,因为取走的数值
            this.notify();//让沉睡线程醒过来


        }
    }
    
}

2.设置生产者和消费者线程

package org.example.testjul;

public class producedata extends  Thread {
    //这就是生产者,生产数据的
    private ValueOf produce;

    public producedata(ValueOf produce) {
        this.produce = produce;//必须是同一把锁,我们将对象看做是一把锁,那么就必须是同一个对象才行,同一个对象
        //作为一把锁,进出同一个同步代码块才有意义
    }

    @Override
    public void run(){
        while(true){
            produce.setValue();//一直作为生产者调用生产方法
        }
    }
}

package org.example.testjul;

public class consumption extends Thread{
    private ValueOf value;

    public consumption(ValueOf value) {
        this.value = value;
    }

    @Override
    public void run() {
        while (true){
            value.getValue();
            //消费者就是一个不断调用消费线程
        }

    }
}

测试类,记得是同一个对象作为锁哦

package org.example.testjul;

public class Test {
    public static void main(String[] args) {
        //生产者和消费者中,那个成员变量必须统一起来,然后用一把锁去给锁住
        ValueOf valueOf = new ValueOf();//这个类的,同一个对象,就是一把锁
        producedata producedata = new producedata(valueOf);
        consumption consumption = new consumption(valueOf);
        //生产消费者线程
        producedata.start();//记得先生产然后消费哦
        consumption.start();
        //这样生产消费,永不停歇,记住,同一个对象才能锁住,同一个代码区。锁只能有一把,有多吧就出事了。
    }
}

这个那个先启动后启动没有关系的
为什么呢,因为wait并不会控制锁,wait会释放锁的,也就是说无论谁沉睡了,都会被叫醒的。

上面那是一个生产者,一个消费者情况,我们最终要测试的事多个生产者,多个消费者的情况。

多个生产者和消费者情况下,一定要使用notifyAll这个命令
明白不,不然每次随机唤醒一个线程,结果发现这个线程字符串还是空的,结果这个线程又沉睡了。你随机唤醒那个线程,无论是生产者还是消费者,都有可能是空的,然后这次就就浪费了

有可能进入假死状态notify在多个生产消费者时候,假死了
所有生产者和消费者都进入wait状态了,没人去唤醒所有人了。

在这里插入图片描述
工作中wait那个判断条件最好用while循环
被唤醒后,最好去判断一下,自己符合不符合条件,因为大家都被锁住了,谁不不能保证谁一定被唤醒了。
让您醒来之后,重新判断一下自己是不是符合标准。

两个线程交替打印。上面那个是使用synorcized打印的,我们接下来要使用Lock锁进行
lock锁重点在于要先获得锁对象
然后我们需要condition对象,可以唤醒指定线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值