SynchronousQueue
SynchronousQueue是一个不存储元素的阻塞队列。每一个put操作必须等待一个take操作,否则他不能继续添加元素。
它支持公平的访问队列。默认情况下线程采用非公平性策略访问队列。使用以下构造方法可以创建公平性访问的SynchronousQueue,如果设置为true,则等待的线程会采用先进先出的顺序访问队列。
public SynchronousQueue(boolean fair) { |
几点说明:
1)SynchronousQueue 时存储数据的队列,阻塞队列。使用场景:适合短期的小并发场景,且数据处理相当快速。
首先该类没有缓冲容量,可以避免在服务器宕机的情况下,从queue的角度来说,没有数据丢失这一说。SynchronousQueue 可以看成是一个传球手,负责把生产者线程处理的数据直接传递 给消费者线程。队列本身并不存储任何元素,非常适合传递性场景。SynchronousQueue 的吞吐量高于 LinkedBlockingQueue 和 ArrayBlockingQueue。
2)CachedThreadPool中使用的就是SynchronousQueue。CachedThreadPool的使用场景就是处理快速的短期的小并发场景。CachedThreadPool中是没有核心线程数的,完全依赖最大线程数,直接依赖操作系统创建线程,如果是短期的小并发,在线程达到keepalive时间以后,可以自行销毁。
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) { |
LinkedTransferQueue
LinkedTransferQueue 是一个由链表结构组成的无界阻塞 TransferQueue 队列。相对于 其他阻塞队列,LinkedTransferQueue 多了 tryTransfer 和 transfer 方法。
transfer
方法如果当前有消费者正在等待接收元素(消费者使用take()方法或带时间限制的poll()方法时),transfer 方法可以把生产者传入的元素立刻 transfer给消费者(跟SynchronousQueue类似)。如果没有消费者在等待接收元素,transfer 方法会将元素存放在队列的 tail 节点,并等到该元素被消费者消费了才返回。
tryTransfer
方法tryTransfer 方法是用来试探生产者传入的元素是否能直接传给消费者。如果没有消费者等待接收元素,则返回 false。和 transfer方法的区别是 tryTransfer 方法无论消费者是否接收,方法立即返回,而 transfer 方法是必须等到消费者消费了才返回。
对于带有时间限制的
tryTransfer(E e,long timeout,TimeUnit unit)
方法,试图把 生产者传入的元素直接传给消费者,但是如果没有消费者消费该元素则等待指定的时间 再返回,如果超时还没消费元素,则返回 false,如果在超时时间内消费了元素,则返回 true。
LinkedBlockingDeque
LinkedBlockingDeque 是一个由链表结构组成的双向阻塞队列。所谓双向队列指的是可以从队列的两端插入和移出元素。双向队列因为多了一个操作队列的入口,在多线程同时入队时,也就减少了一半的竞争。
在初始化 LinkedBlockingDeque 时可以设置容量防止其过度膨胀。另外,双向阻塞队列可以运用在“工作窃取”模式中。
应用场景:没有严格的顺序控制的场景使用。比如将10个任务添加到双端队列,起两个线程进行任务处理(处理顺序无所谓,只要都处理完汇总即可),选择双端队列会减少竞争。