本身总结 :并发队列ConcurrentLinkedQueue、阻塞队列AraayBlockingQueue、阻塞队列LinkedBlockingQueue 区别 和 使用场景总结

并发队列ConcurrentLinkedQueue、阻塞队列AraayBlockingQueue、阻塞队列LinkedBlockingQueue 区别 和  使用场景总结

分类: Java
 
三者区别与联系: 联系,三者 都是线程安全的。区别,就是 并发  和 阻塞,前者为并发队列,由于采用cas算法,因此可以高并发的处理;后2者采用锁机制,因此是阻塞的。注意点就是前者因为采用cas算法,虽然能高并发,但cas的特色形成操做的危险性,怎么危险性能够去查一下cas算法(但一些多消费性的队列仍是用的它,缘由看下边使用场景中的说明)
 
后2者区别:联系,第2和第3都是阻塞队列,都是采用锁,都有阻塞容器Condition,经过Condition阻塞容量为空时的取操做和容量满时的写操做第。区别,第2就一个整锁,第3是2个锁,因此第2第3的锁机制不同,第3比第2吞吐量 大,并发性能也比第2高。
后2者的具体信息:   LinkedBlockingQueue是BlockingQueue的一种使用Link List的实现,它对头和尾(取和添加操做)采用两把不一样的锁,相对于ArrayBlockingQueue提升了吞吐量。它也是一种阻塞型的容器,适合于实现“消费者生产者”模式。

ArrayBlockingQueue是对BlockingQueue的一个数组实现,它使用一把全局的锁并行对queue的读写操做,同时使用两个Condition阻塞容量为空时的取操做和容量满时的写操做。web

 正由于LinkedBlockingQueue使用两个独立的锁控制数据同步,因此可使存取两种操做并行执行,从而提升并发效率。而ArrayBlockingQueue使用一把锁,形成在存取两种操做争抢一把锁,而使得性能相对低下。LinkedBlockingQueue能够不设置队列容量,默认为Integer.MAX_VALUE.其容易形成内存溢出,通常要设置其值。算法

使用场景总结:
适用阻塞队列的好处:多线程操做共同的队列时不须要额外的同步,另外就是队列会自动平衡负载,即那边(生产与消费两边)处理快了就会被阻塞掉,从而减小两边的处理速度差距,自动平衡负载这个特性就形成它能被用于多生产者队列,由于你生成多了(队列满了)你就要阻塞等着,直到消费者消费使队列不满你才能够继续生产。 当许多线程共享访问一个公共 collection 时,ConcurrentLinkedQueue 是一个恰当的选择。
LinkedBlockingQueue 多用于任务队列(单线程发布任务,任务满了就中止等待阻塞,当任务被完成消费少了又开始负载 发布任务)
ConcurrentLinkedQueue  多用于消息队列(多个线程发送消息,先随便发来,不计并发的-cas特色)
 
多个生产者,对于LBQ性能还算能够接受;可是多个消费者就不行了mainLoop须要一个timeout的机制,不然空转,cpu会飙升的。LBQ正好提供了timeout的接口,更方便使用 若是CLQ,那么我须要收处处理sleep
单生产者,单消费者  用 LinkedBlockingqueue  
多生产者,单消费者   用 LinkedBlockingqueue  
单生产者 ,多消费者   用 ConcurrentLinkedQueue
多生产者 ,多消费者   用 ConcurrentLinkedQueue
对上边总结:
如消息队列,好多client发来消息,根据client发送前后放入队列中,先发送的就先放进来,而后因为队列是先进先出,是一个一个出来的,因此不涉及到线程安全问题,因此用LinkedBlockingqueue  队列。好比还拿上边消息队列那个例子,因为队列是一个一个出来的,出来一个消息协议体就由线程池分配一个线程去处理这个消息体,这个消息体对于线程池来讲谈不上共享不共享的问题,即不会多个线程去抢同一个消息体去执行,因此就不须要用线程安全的队列结构了;那假如一种状况,队列里仍然是一个一个的出来,可是出来的这个元素是 线程池共享的,即你们线程都须要用到这个从队列里出来的这个元素,也就是多消费者消费同一个东西这种状况,因此就要用线程安全的队列了,即ConcurrentLinkedQueue。
相关文章
相关标签/搜索