阻塞队列
BlockingQueue的实现类有:
- ArrayBlockingQueue(有界队列):使用该对象时,若有新任务需要执行,如果线程池的实际线程数少于corePoolSize,则会优先创建新的线程,若大于,则会将新任务加入到等待队列。当队列满时,则在总线程数不大于maximumPoolSize的前提下,创建新的线程执行任务。
- SynchronousQueue(同步移交队列):它是一个特殊的队列,它的名字其实就蕴含了它的特征 同步的队列。为什么说是同步的呢?这里说的并不是多线程的并发问题,而是因为当一个线程往队列中写入一个元素时,写入操作不会立即返回,需要等待另一个线程来将这个元素拿走;同理,当一个读线程做读操作的时候,同样需要一个相匹配的写线程的写操作。这里的 Synchronous 指的就是读线程和写线程需要同步,一个读线程匹配一个写线程。
- LinkedBlockingQueue(无界队列):使用该对象时,除非系统资源耗尽,否则不存在入队失败的情况。当有新任务来时,若系统的线程数量小于corePoolSize,线程池会生成新的线程执行,当线程数达到corePoolSize时就不会再继续增加了,而是将任务加入到等待队列,该队列会保持无限增长。(默认最大值,易造成OOM)
- PriorityBlockingQueue(优先任务队列):该功能由PriorityBlockingQueue实现。该类是一个特殊的无界队列。ArrayBlockingQueue和LinkedBlockingQueue都是按照先进先出处理任务,而该类则可以根据任务自身的优先级顺序先后执行。
拒绝策略
RejectedExecutionHandler 局决策略有:
AbortPolicy中止策略:该策略是默认饱和策略。使用该策略时在饱和时会抛出RejectedExecutionException(继承自RuntimeException),调用者可捕获该异常自行处理。
/** * Always throws RejectedExecutionException. */ public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { throw new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString()); }
DiscardPolicy抛弃策略:不做任何处理直接抛弃任务
/** * Does nothing, which has the effect of discarding task r. */ public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { }
DiscardOldestPolicy:抛弃旧任务策略 先将阻塞队列中的头元素出队抛弃,再尝试提交任务。如果此时阻塞队列使用PriorityBlockingQueue优先级队列,将会导致优先级最高的任务被抛弃,因此不建议将该种策略配合优先级队列使用。
/** * Obtains and ignores the next task that the executor * would otherwise execute, if one is immediately available, * and then retries execution of task r, unless the executor * is shut down, in which case task r is instead discarded. */ public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) { e.getQueue().poll(); e.execute(r); } }
CallerRunsPolicy:不会抛弃任何任务, 在调用者的线程中执行任务,除非执行器
*已关闭,在这种情况下任务将被丢弃/** * Executes task r in the caller's thread, unless the executor * has been shut down, in which case the task is discarded. */ public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) { r.run(); } }