无界阻塞队列
SynchronousQueue
无界阻塞队列
没有存储容量的阻塞队列;通过信息的传递来实现生产者线程和消费者线程的阻塞和唤醒
生产者put()元素 假如没有消费者则生产者会阻塞;消费者take()元素,假如没有生产者 消费者也会阻塞
newCachedThreadPool:可以缓存的线程池 可以处理非常大的请求任务,假如有1000个任务 那么线程池需要分配1000个线程来执行
| public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue } |
SynchronousQueue 初始化,因为会阻塞多个生产者 线程或者阻塞多个消费者线程,需要一个容器(队列TransferQueue或者 栈TransferStack)存储处于阻塞下的生产者线程 或者处于阻塞下的消费者线程 然后通过一个消息来传递
| public SynchronousQueue() { this(false); } public SynchronousQueue(boolean fair) { transferer = fair ? new TransferQueue } |
说明:
公平性(链表):生产者线程put时,当找不到或者没有对应的消费者线程消费的时候会被封装成一个Qnode加入如上单向链表,当有消费者线程去消费的时候会从以上队列拿到一个生产者线程消费
非公平性(栈):
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue());
}
newCachedThreadPool:可以用来处理峰值的请求,假如来了1000个线程丢到线程池,必须要找到一个消费者线程来处理 假如没有找到消费者线程就new 因为最大的线程池数=Integer.MAX_VALUE ,
每一个线程的有效时长=60s
linkedTransferQueue
无界阻塞队列
transfer 能力:一个生产者线程 必须对应一个消费者线程
= linkedBlockedQueue + TransferQueue
linkedBlockingQueue
无界队列 基于链表结构
linkedBlockingDeque
双端队列 双向链表组成的队列 支持双向插入删除 在一定程度上能够解决多线程竞争问题 :可以有一半的线程在左边插入 另一半的线程在右边插入
Fork/Join 有相关应用 ,以下列出相关方法
阻塞队列的使用
异步mq使用场景 减少同步请求带来的阻塞损耗
责任链:构建一条执行链 结果传递
总结:但凡涉及到生产者消费者模式的都可以使用阻塞队列 然后异步化 例子:分布式mq



