阻塞队列 生产者-消费者模式 窃取工作模式(java并发编程实践读书笔记二)

来源:互联网 发布:程序员是做什么的 编辑:程序博客网 时间:2024/04/29 14:49

阻塞队列 生产者-消费者模式 窃取工作模式

    生产者-消费者模式

        简化了开发,因为它解除了生产者类和消费者类之间相互依赖的代码;解耦不同速度的生产,消费等活动。
        围绕队列展开设计,生产者把数据放进队列,不用考虑消费者的消费能力,甚至可以根本没有消费者。类似的,消费者也不需要知道生产者是谁,只要从队列中获取数据即可。
        阻塞队列可以使用任意数量的生产者和消费者

    窃取工作模式

        每个消费者都有一个自己的双端队列。如果一个消费者完成了自己的双端队列中的全部工作,它可以偷取其他双端队列中 末尾 的任务
        优点:工作的线程不会竞争一个共享的任务队列,所以该模式更具有可伸缩性;
                  减少竞争,即使要从其他双端队列中获取任务,也是从 末尾 获取,不会与原本线程发生竞争
                  解决消费者与生产者同体的问题:当一个消费者线程在执行任务的过程中,发现了更多的的任务,就把新发现的任务放到自己队列的末尾(或者其他工作者的队列中)例如:网络爬虫在处理一个页面时,发现了更多新的页面。

    java5.0新增的容器类型

        Queue                   接口 java.util

        BlockingQueue    接口 java.util.concurrent

            提供了可阻塞的put和take方法,等价于可定时的offer和poll
            如果Queue已满,则put方法会阻塞,直到有空间可用
            如果Queue为空,则take方法会阻塞,直到有元素可用
            
            offer 和 poll 接受一个额外的时间参数,在这个时间之内等待,超出这个时间则返回false,操作成功则返回ture
            不建议使用add方法增加元素,在空间不足的情况下,add方法抛出异常,建议单纯的新增使用offer

           BlockingQueue    实现

                    LinkedBlockingQueue
                    ArrayBlockingQueue
                    上面两个是FIFO队列,类似与LinkedList与ArrayList ,拥有比同步List更好的并发性能
                    PriorityBlockingQueue
                    按照优先级排序的队列,可以在构造的时候提供一个Compararot,进行排序
                    SynchronousQueue
                    一种阻塞队列,其中每个插入操作必须等待另一个线程的对应移除操作 ,反之亦然。同步队列没有任何内部容量,甚至连一个队列的容量都没有。不能在同步队列上进行peek,因为仅在试图要移除元素时,该元素才存在;除非另一个线程试图移除某个元素,否则也不能(使用任何方法)插入元素;也不能迭代队列,因为其中没有元素可用于迭代。
                    同步队列类似于 CSP 和 Ada 中使用的 rendezvous 信道。它非常适合于传递性设计,在这种设计中,在一个线程中运行的对象要将某些信息、事件或任务传递给在另一个线程中运行的对象,它就必须与该对象同步。

    java6.0新增的容器类型

        Deque

        BlockingDeque

            双端队列,允许在头和尾分别进行插入和移除 实现类 ArrayDeque,LinkedBlockingDeque

        

     补充:有界队列

                当生产者的速度大于消费者时,使用没有边界的队列,最终会耗尽内存。
                使用有界队列,配合offer方法(可以返回失败状态),可以在创建更多灵活的策略
                    减轻负载
                    把剩余的工作条目接入硬盘
                    减少生产者线程
                    ...
 
 
原创粉丝点击