生产者和消费者问题(四)中

简介: 生产者和消费者问题(四)

三. 生产者和消费者同步 第二版


将上面的程序进行改写。


三.一 同步产品类 Info


里面有两个同步的方法。


public class Info {
    private String name;
    private String content;
    public Info(){
    }
    //设置产品
    public synchronized  void setInfo(String name,String content){
        this.setName(name);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.setContent(content);
    }
    //取出产品
    public synchronized  void getInfo(){
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(this.getName()+"---->"+this.getContent());
    }
    public String getName() {
        return this.name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getContent() {
        return this.content;
    }
    public void setContent(String content) {
        this.content = content;
    }
}


三.二 生产者 Productor


public class Productor implements  Runnable {
    private Info info=null;
   private boolean isFirst=true;
    public Productor(Info info){
        this.info=info;
    }
    @Override
    public void run() {
        for(int i=0;i<50;i++){
            System.out.println("输出 i:"+i+",isFirst:"+isFirst);
            if(isFirst){  //是第一个,那么就生产第一个消息
                this.info.setInfo("两个蝴蝶飞","这是两个蝴蝶飞");
                isFirst=false;
            }else{
                this.info.setInfo("老蝴蝶","这是老蝴蝶");
                isFirst=true;
            }
        }
    }
}


三.三 消费者 Consumer


public class Consumer implements Runnable {
    private Info info=null;
    public Consumer(Info info){
        this.info=info;
    }
    @Override
    public void run() {
        for(int i=0;i<50;i++){
            System.out.println("");
            //获取信息
            this.info.getInfo();
        }
    }
}


三.四 主程序测试Demo


public class Demo {
    public static void main(String[] args) {
        //定义生产者
        Info info=new Info();
        //生产
        Productor productor=new Productor(info);
        //消费
        Consumer consumer=new Consumer(info);
        Thread thread=new Thread(productor);
        Thread thread1=new Thread(consumer);
        //启动
        thread.start();
        thread1.start();
    }
}


三.五 测试运行,发现问题


20200619190105875.png


常常会先生产这一部分,后生产那一部分, 并不是生产一个,拿一个。


需要用 Object 对象的 wait() 和 notify(), notifyAll() 方法进行设置。


四. 等待和唤醒 生产者和消费者第三版


在Info 对象里面设置一个标识位, 如果生产了一件产品,那么就生产者先等待,让消费者去消费好之后,再重新生产,避免多次生产一件产品。


四.一 等待和唤醒 Info


package com.yjl.thread.cp.c3;
/**
 * package: com.yjl.thread.cp
 * className: Info
 * Description: 请输入相应的描述
 *
 * @author : yuezl
 * @Date :2020/6/13 12:53
 */
public class Info {
    private String name;
    private String content;
    //定义标识位
    private boolean flag=false;
    public Info(){
    }
    public synchronized  void setInfo(String name,String content){
        if(flag){  //为真
            try {
                super.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.setName(name);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.setContent(content);
        flag=true;
        //当前只有一个线程,唤醒一个线程, 也可以直接唤醒多个。
        super.notifyAll();
    }
    public synchronized  void getInfo(){
        if(!flag){
            try {
                super.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(this.getName()+"---->"+this.getContent());
        flag=false;
        //当前只有一个线程,唤醒一个线程, 也可以直接唤醒多个
        super.notifyAll();
    }
    public String getName() {
        return this.name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getContent() {
        return this.content;
    }
    public void setContent(String content) {
        this.content = content;
    }
}


生产者,消费者和 Demo 均与 第二版的内容一样。


运行程序,控制台打印输出


20200619190119722.png


发现,可以做到每次生产一个产品,取出一个产品的功能了。


但是,这种情况下,只有一个生产者和一个消费者,如果都有两个呢?


20200619190135464.png


其实,我们可以先创建一个仓库, 当生产时,可以将产品放置到仓库里面, 当仓库满时,才不让继续生产, 如果仓库没有满,就继续生产。 当仓库没有产品时,就不让继续消费了。



相关文章
|
1月前
|
消息中间件
RabbitMQ创建生产者和消费者
RabbitMQ创建生产者和消费者
24 0
|
1月前
|
消息中间件 RocketMQ
RocketMq消费者/生产者配置
RocketMq消费者/生产者配置
|
1月前
|
负载均衡 Java API
SpringCloud深入理解 | 生产者、消费者
SpringCloud深入理解 | 生产者、消费者
49 0
|
11月前
|
消息中间件
ActiveMQ消费者消费消息(点对点模式)
上篇博客写了生产者生产消息:ActiveMQ向消息队列存入消息
|
安全 数据处理
线程中的生产者和消费者模式
线程中的生产者和消费者模式
105 0
线程中的生产者和消费者模式
|
设计模式 安全
生产者与消费者模型
生产者与消费者模型
76 0
生产者与消费者模型
|
前端开发 Java Nacos
服务生产者 | 学习笔记
快速学习服务生产者。
64 0
服务生产者 | 学习笔记
2.6操作系统(生产者消费问题 多生产者—消费者问题 吸烟者问题)
1.生产者消费问题 能否改变相邻P、V操作的顺序? 2.多生产者—消费者问题 如何实现? 可不可以不用互斥信号量? 如果盘子(缓冲区)容量为2 知识回顾与重要考点 3.吸烟者问题 如何实现
2.6操作系统(生产者消费问题 多生产者—消费者问题 吸烟者问题)
|
消息中间件 存储 SQL
MQ系列6:消息的消费
MQ系列6:消息的消费
196 0
MQ系列6:消息的消费
一个简单的生产者和消费者客服实现
一个简单的生产者和消费者客服实现
119 0