并发队列Queue使⽤场景总结日常日记
并发队列ConcurrentLinkedQueue、阻塞队列AraayBlockingQueue、阻塞队列LinkedBlockingQueue 区别和使⽤场景总结
番茄面三者区别与联系: 联系,三者都是线程安全的。区别,就是并发和阻塞,前者为并发队列,因为采⽤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阻塞容量为空时的取操作和容量满时的写操作。
正因为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。