生产者消费者模型

线程实现生产者和消费者模型,用到wait()等待和notify()唤醒机制, 

注意:等待唤醒机制是建立线程安全的基础之上设置的。

Student类:

public class Student {
    private String name;
    private int age;
    private boolean flag; // boolean类型的默认值在内存是false

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public boolean getFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

Product生产者类:

public class ProductThread extends Thread{
    private Student s;
    private int i = 0;

    public ProductThread(Student s) {
        this.s = s;
    }

    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(30);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (s){
                //应该先看一看数据有没有被消费,若被消费了,才赋新的值,通知消费者消费,若没有消费,等待消费者消费
                if(s.getFlag()){
                    //若学生对象中flag成员变量值是true,生产就不会生产
                    //由多个线程共享且唯一的锁对象进行等待
                    try {
                        s.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                if(i%2==0){
                    s.setName("光头强");
                    s.setAge(19);
                }else {
                    s.setName("熊大");
                    s.setAge(18);
                }
                i++;
                s.setFlag(true);
                //赋值之后应该通知消费者进行消费数据
                s.notify();
            }
        }

    }
}

Consumer消费者类:

public class ConsumerThread extends Thread {
    private Student s;

    public ConsumerThread(Student s) {
        this.s = s;
    }

    @Override
    public void run() {
//        Student s = new Student();
        while (true) {
            try {
                Thread.sleep(30);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (s) {
                //消费者消费数据之前,先判断数据有没有生产,若生产了,就取值打印,若没有生产,就等待,通知生产者生产
                if (!s.getFlag()) {
                    try {
                        s.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                System.out.println(s.getName() + "-" + s.getAge());
                s.setFlag(false);
                //通知生产者赋值新的数据
                s.notify();
            }
        }
    }
}

测试类:

 等待唤醒机制:
        共享数据:学生对象(name,age)
        生产者线程:对学生对象进行赋值操作
        消费者线程:对学生对象进行取值操作


    为了观察更好的效果,我们可以让生产者赋值不同的信息
    这时候出现了重复取值和姓名与年龄对应不上的情况
    检测线程程序是否存在安全问题的三要素:
        1、是否存在多线程环境?是 生产者和消费者
        2、是否存在共享数据?是 student
        3、是否存在多条语句操作共享数据?是

    解决方案:
        1、加入同步代码块
        2、加入lock锁

    虽然解决了线程安全的问题,但是结果并不是我们想要的结果,在生产者消费者模型中,消费一次应该通知生产者生产。等待唤醒机制。
    注意:等待唤醒机制是建立线程安全的基础之上设置的。


 */
public class StudentDemo {
    public static void main(String[] args) {
        Student s = new Student();

        ProductThread p1 = new ProductThread(s);
        ConsumerThread c1 = new ConsumerThread(s);
        p1.start();
        c1.start();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我的K8409

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值