一、
在并发队列上JDK提供了两套实现,一个是以ConcurrentLinkedQueue为代表的高性能队列。一个是以blockingQueue接口为代表的阻塞队列。
二、
ConcurrentLinkedQueue:
是一个适用于高并发场景下的队列,通过无锁的方式,实现了高并发状态下的高性能。通常ConcurrentLinkedQueue性能好于BlockingQueue。它是一个基于链接节点的无界线程安全队列,该队列的元素遵循先进先出的原则。该队列不允许null。
ConcurrentLinkedQueue的重要方法:
add()和offer()都是加入方法(两者并无啥区别,只是因为Queue接口要求了实现,在其他实现类里面这两个方法就能有不同的功能)
poll()和 peek()都是取头元素的节点,区别在于前者会删除,后者不会。
BlockingQueue接口:
ArrayBlockingQueue:基于数组的阻塞队列实现,在ArrayBlockingQueue内部,维护了一个定长数组,以便缓存队列中的数据对象。其内部没有实现读写分离,也就意味了生产和消费不能并行,长度是需要定义的。可以指定先进先出或者先进后出,也叫有界队列,适用于很多场景。
LinkedBlockingQueue:基于链表的阻塞队列,同ArrayBlockingQueue类似。其内部也维持着一个数据缓冲队列。LinkedBlockingQueue之所以能够高效的处理并发数据,是因为其内部实现采用分离锁,从而实现生产者和消费者并发运行。它是一个无界队列。
SynchronousBlockingQueue: 一种没有缓冲的队列,生产者生产的数据会直接被消费者获取并消费。
PriorityBlockingQueue:基于优先级的阻塞队列(传入队列的对象必须实现Comparable接口),在实现PriorityBlockingQueue时,内部控制线程同步的锁采用的是公平锁,他也是一个无界队列。
DelayQueue: 带有延迟时间的Queue,其中的元素只有当其指定的延迟时间到了,才能够从队列中获取该元素。DelayQueue中的元素必须实现Delayed接口。DelayQueue是一个没有大小限制的队列, 应用场景很多。比如对缓存超时的数据进行移除,任务超时处理,空闲连接的关闭等等。
三、
主要的是ArrayBlockingQueue、LinkedBlockingQueue、SynchronousBlockingQueue三个队列。ArrayBlockingQueue适用于当数据量很多时,指定一定长度的数据避免存储的数据过大,多余的线程就处于阻塞状态。LinkedBlockingQueue适用于一定范围内的数据量,原则上没有上限,也可以通过构造器指定长度大小变成有界队列。一般适用于距离预期目标有允许有一定偏差的场景。SynchronousBlockingQueue适用于极少数数据的场景,没必要对数据进行缓存让消费者直接获取数据。三个缓存可以在一定场景下,根据不同的时间,状态进行切换。