一、线程池阻塞队列有哪几种
线程池阻塞队列有四种类型的阻塞队列:
- 无界队列
- 有界队列
- SynchronousQueue
- DelayQueue
二、线程池阻塞队列的选择
根据业务特点,我们需要选择合适的阻塞队列类型。如果线程池的线程数是无限的,可以选择无界队列;如果线程池的线程数是有限的,可以选择有界队列或SynchronousQueue;如果需要实现延迟执行任务,可以选择DelayQueue。
三、线程池阻塞队列的概念
线程池阻塞队列是指在任务提交到线程池后,如果线程池的线程数量已经达到最大值,那么剩余的任务将会被放到一个阻塞队列中,这个队列就是线程池的阻塞队列。
四、线程池阻塞队列大小设置
线程池阻塞队列大小设置与业务需求有关。如果业务中提交的任务量较大,可以适当增加队列大小,以避免任务被拒绝。但是要注意,队列过大可能会导致oom,因此需要在合理的范围内设置队列大小。
五、线程池阻塞队列源码
public interface BlockingQueueextends Queue { //添加元素到队尾,如果队列已满,将会阻塞 void put(E e) throws InterruptedException; //从队头获取元素,如果队列为空,将会阻塞 E take() throws InterruptedException; } public class LinkedBlockingQueue extends AbstractQueue implements BlockingQueue , Serializable { //默认队列大小为Integer.MAX_VALUE public LinkedBlockingQueue() { this(Integer.MAX_VALUE); } //指定队列大小 public LinkedBlockingQueue(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); this.capacity = capacity; last = head = new Node (null); } private static class Node { E item; Node next; Node(E x) { item = x; } } //添加元素到队尾,如果队列已满,将会阻塞 public void put(E e) throws InterruptedException { if (e == null) throw new NullPointerException(); int c = -1; Node node = new Node (e); final ReentrantLock putLock = this.putLock; final AtomicInteger count = this.count; putLock.lockInterruptibly(); try { while (count.get() == capacity) { notFull.await(); } enqueue(node); c = count.getAndIncrement(); if (c + 1 < capacity) notFull.signal(); } finally { putLock.unlock(); } if (c == 0) signalNotEmpty(); } //从队头获取元素,如果队列为空,将会阻塞 public E take() throws InterruptedException { E x; int c = -1; final AtomicInteger count = this.count; final ReentrantLock takeLock = this.takeLock; takeLock.lockInterruptibly(); try { while (count.get() == 0) { notEmpty.await(); } x = dequeue(); c = count.getAndDecrement(); if (c > 1) notEmpty.signal(); } finally { takeLock.unlock(); } if (c == capacity) signalNotFull(); return x; } }
六、线程池阻塞队列与拒绝策略
线程池阻塞队列与拒绝策略是相辅相成的,当任务提交到线程池后,如果线程池中的线程已经达到最大值并且线程池阻塞队列已经满了,就需要使用拒绝策略处理剩余的任务。
七、线程池阻塞队列的作用
线程池阻塞队列的作用是缓存任务,避免任务被拒绝。当线程池中的线程数量已经达到最大值后,剩余的任务就会放到阻塞队列中等待处理。
八、线程池阻塞队列导致oom
线程池阻塞队列如果过大,可能会导致oom。因此,在设置队列大小时需要注意避免过大。
九、线程池阻塞队列满了
当线程池阻塞队列满了,新提交的任务就会被拒绝。此时可以使用拒绝策略来处理剩余的任务。
十、线程池阻塞队列的长度选取
选择线程池阻塞队列的长度应该考虑业务需求。如果任务量很大,可以适当增加队列大小;如果希望更快的响应任务,可以适当减小队列大小。