生产者消费者模型

生产者消费者模型

生产者-消费者(producer-consumer)问题,称之为有界缓冲区问题,两个线程共享一个固定的大小的缓冲区
其中一个是生产者、生产消息存放到缓冲区、另一个是消费者,在缓冲区取出消息
在这里插入图片描述

生产者消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一存储空间,生产者向空间里生产数据,而消费者取走数据。
由于程序运行是线程不安全的,因此可能会出现以下问题:
1、假设生产者线程刚向数据存储空间添加了数据的名称,还没有加入该信息的内容,程序就切换到了消费者线程,消费者线程将把信息的名称和上一个信息的内容联系在一起;
2、生产者生产了若干次数据,消费者才开始取数据,或者是,消费者取完一次数据后,还没等生产者放入新的数据,又重复取出了已取过的数据。
问题1:
要靠同步来解决
问题2:
需要线程间通信,生产者线程放入数据后,通知消费者线程取出数据,消费者线程取出数据后,通知生产者线程生产数据,这里用wait/notify机制来实现。
例子:

class Info{ // 定义信息类
        private String name = "name";//定义name属性,为了与下面set的name属性区别开
        private String content = "content" ;// 定义content属性,为了与下面set的content属性区别开
        private boolean flag = true ;   // 设置标志位,初始时先生产
        public synchronized void set(String name,String content){
            while(!flag){
                try{
                    super.wait() ;
                }catch(InterruptedException e){
                    e.printStackTrace() ;
                }
            }
            this.setName(name) ;    // 设置名称
            try{
                Thread.sleep(300) ;
            }catch(InterruptedException e){
                e.printStackTrace() ;
            }
            this.setContent(content) ;  // 设置内容
            flag  = false ; // 改变标志位,表示可以取走
            super.notify();
        }
        public synchronized void get(){
            while(flag){
                try{
                    super.wait() ;
                }catch(InterruptedException e){
                    e.printStackTrace() ;
                }
            }
            try{
                Thread.sleep(300) ;
            }catch(InterruptedException e){
                e.printStackTrace() ;
            }
            System.out.println(this.getName() + 
                " --> " + this.getContent()) ;
            flag  = true ;  // 改变标志位,表示可以生产
            super.notify();
        }
        public void setName(String name){
            this.name = name ;
        }
        public void setContent(String content){
            this.content = content ;
        }
        public String getName(){
            return this.name ;
        }
        public String getContent(){
            return this.content ;
        }
    }
    class Producer implements Runnable{ // 通过Runnable实现多线程
        private Info info = null ;      // 保存Info引用
        public Producer(Info info){
            this.info = info ;
        }
        public void run(){
            boolean flag = true ;   // 定义标记位
            for(int i=0;i<10;i++){
                if(flag){
                    this.info.set("姓名--1","内容--1") ;    // 设置名称
                    flag = false ;
                }else{
                    this.info.set("姓名--2","内容--2") ;    // 设置名称
                    flag = true ;
                }
            }
        }
    }
    class Consumer implements Runnable{
        private Info info = null ;
        public Consumer(Info info){
            this.info = info ;
        }
        public void run(){
            for(int i=0;i<10;i++){
                this.info.get() ;
            }
        }
    }
    public class ThreadCaseDemo03{
        public static void main(String args[]){
            Info info = new Info(); // 实例化Info对象
            Producer pro = new Producer(info) ; // 生产者
            Consumer con = new Consumer(info) ; // 消费者
            new Thread(pro).start() ;
            //启动了生产者线程后,再启动消费者线程
            try{
                Thread.sleep(500) ;
            }catch(InterruptedException e){
                e.printStackTrace() ;
            }

            new Thread(con).start() ;
        }
    }
本人才疏学浅,如有错误,烦请指出,谢谢!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值