美文网首页
生产者/消费者模式

生产者/消费者模式

作者: hekirakuno | 来源:发表于2019-09-29 14:42 被阅读0次

    生产者/消费者模式是一种非常典型的多线程场景,理解起来其实也非常简单。
    我们就用最其名称的字面意思来梳理一下。
    试想一下生活中的生产者,消费者是都是充当着什么样的角色?

    作为一个游走在死宅边缘的异次元生物,对于手办总有一些莫名的追求。我们就用它来做场景的讲解吧。
    手办的生产者--就叫他们,手作屋吧。
    手办的消费者--没错,就是我,和其他死宅们。

    手作屋家的叶修手办在全职高手货架,总共有10个货位。
    手作屋们每制作一个手办,就会把它放进货位上;
    作为叶修粉的死宅们看到上架一个手办,就会把它买走;
    如果货位满了,手作屋们就不再上货新的手办,直到有人买走,货位出现空位为止;
    同样的,如果手办告罄,消费者们就无法购买手办。
    而这个货架呢,就是生产者/消费者模式中,常用的缓存容器了。

    所以现在我们重新梳理一下,生产者/消费者模式。

    必要元素:生产者,消费者,容器。

    在代码中,我们经常使用栈/队列充当容器的作用。因为他们都有快速上架、销售(入栈(队)出栈(队))的方法。

    好,在java中,一个面向对象编程语言,我们先来看看对象都有谁。
    生产者,手作屋在自己埋头苦干,做完就上架;
    消费者,瞄准货架,有货就买;
    两者完全没什么关系,大家的目标都是货架罢了。

    所以,我们先让生产者动起来,毕竟没有生产力,消费者再有钱也买不到。

    import java.util.concurrent.BlockingQueue;
    
    //集成Runnable接口,重写run方法。
    public class Provider implements Runnable{
        //货架(final是不可变的,所以这个queue是惟一的货架)
        private final BlockingQueue queue;
        //需求量
        int total = 10;
        //给手作屋指定货架
        Provider (BlockingQueue queue){
            this.queue = queue;
        }
        //手作屋的工作
        @Override
        public void run() {
            //我们就简单看一下制作10个手办的过程吧
            for(int i = 0;i<total;i++){
                try {
                    //上货
                    queue.put(i);
                    System.out.println("provider:"+i);
                } catch (InterruptedException e) {
                    //log e.printStackTrace();
                }
            }
        }
    }
    

    消费者,但凡有货我就买买买。

    public class Consumer implements Runnable{
        //final修饰的,全世界惟一的货架
        private final BlockingQueue queue;
        //给消费者指定货架
        Consumer (BlockingQueue queue){
            this.queue = queue;
        }
      
        @Override
        public void run(){
            //存在即真理,上货就要买。
            while(true){
                try {
                    //queue.take()买买买,消费
                    System.out.println("consumer:"+queue.take());
                } catch (InterruptedException e) {
                    //log e.printStackTrace();
                }
            }
        }
    }
    

    好了,我们定义了生产者和消费者两种对象。
    他们行为如下:
    生产者,每生产一个货物,就会放进队列中;
    消费者,每当队列中有一个货物,就会消费掉。

    BlockingQueue的put()方法保障了队列满了之后不会继续入队;take()方法保障了队列空了之后不会继续出队的边界情况。

    让我们在代码小世界中,启动消费者与生产者的ai,模拟手作屋和死宅的人生吧。

    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.LinkedBlockingQueue;
    
    public class Test {
        public static void main(String[] args){
            //保障上货货架与购物货架是一个货架。
            BlockingQueue queue = new LinkedBlockingQueue();
            Thread provider = new Thread(new Provider(queue));
            Thread consumer = new Thread(new Consumer(queue));
            //手作屋就位
            provider.start();
            //死宅就位
            consumer.start();
        }
    }
    

    相关文章

      网友评论

          本文标题:生产者/消费者模式

          本文链接:https://www.haomeiwen.com/subject/xbmwyctx.html