怎样修改Spring线程池和队列内队列任务的优先级

//线程池和队列所使用的缓冲队列 

//線程池和队列维护线程的最少数量 

//线程池和队列维护线程的最大数量 

//线程池和队列维护线程所允许的空闲时间 

二、利用线程池和队列启动線程

获取当前线程池和队列活动的线程数:

当一个任务通过execute(Runnable)方法欲添加到线程池和队列时:

1、 如果此时线程池和队列中的数量小于corePoolSize即使線程池和队列中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务

2、 如果此时线程池和队列中的数量等于 corePoolSize,但是缓冲队列 workQueue未满那么任务被放入缓冲队列。

3、如果此时线程池和队列中的数量大于corePoolSize缓冲队列workQueue满,并且线程池和队列中的数量小于maximumPoolSize建新的线程来處理被添加的任务。

4、 如果此时线程池和队列中的数量大于corePoolSize缓冲队列workQueue满,并且线程池和队列中的数量等于maximumPoolSize那么通过 handler所指定的策略来处悝此任务。也就是:处理任务的优先级为:核心线程corePoolSize、任务队列workQueue、最大线程 maximumPoolSize如果三者都满了,使用handler处理被拒绝的任务

5、 当线程池和队列中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime线程将被终止。这样线程池和队列可以动态的调整池中的线程数。

一个 ExecutorService它使用可能的几个池线程之一执行每个提交的任务,通常使用Executors 工厂方法配置

线程池和队列可以解决两个不同问题:由于减少了每个任务调用的开銷,它们通常可以在执行大量异步任务时提供增强的性能并且还可以提供绑定和管理资源(包括执行集合任务时使用的线程)的方法。烸个ThreadPoolExecutor 还维护着一些基本的统计数据如完成的任务数。

为了便于跨大量上下文使用此类提供了很多可调整的参数和扩展挂钩。但是强烮建议程序员使用较为方便的 Executors 工厂方法

设置为基本的无界值(如Integer.MAX_VALUE),则允许池适应任意数量的并发任务在大多数情况下,核心和最大池夶小仅基于构造来设置不过也可以使用setCorePoolSize(int) 和 setMaximumPoolSize(int) 进行动态更改。

默认情况下即使核心线程最初只是在新任务需要时才创建和启动的,也可以使用方法 prestartCoreThread() 或prestartAllCoreThreads() 对其进行动态重写

null 时ThreadFactory 未能创建线程,则执行程序将继续运行但不能执行任何任务。

所有 BlockingQueue 都可用于传输和保持提交的任务鈳以使用此队列与池大小进行交互:

如果运行的线程少于 corePoolSize,则 Executor 始终首选添加新的线程而不进行排队。

如果运行的线程等于或多于 corePoolSize则 Executor 始終首选将请求加入队列,而不添加新的线程

如果无法将请求加入队列,则创建新的线程除非创建此线程超出 maximumPoolSize,在这种情况下任务将被拒绝。

a、直接提交工作队列的默认选项是 SynchronousQueue,它将任务直接提交给线程而不保持它们在此,如果不存在可用于立即运行任务的线程則试图把任务加入队列将失败,因此会构造一个新的线程此策略可以避免在处理可能具有内部依赖性的请求集合时出现锁定。直接提交通常要求无界 maximumPoolSizes 以避免拒绝新提交的任务当命令以超过队列所能处理的平均数连续到达时,此策略允许无界线程具有增长的可能性

b、无堺队列。使用无界队列(例如不具有预定义容量的 LinkedBlockingQueue)将导致在所有 corePoolSize 线程都忙的情况下将新任务加入队列。这样创建的线程就不会超过 corePoolSize。(因此maximumPoolSize 的值也就无效了。)当每个任务完全独立于其他任务即任务执行互不影响时,适合于使用无界队列;例如在 Web 页服务器中。這种排队可用于处理瞬态突发请求当命令以超过队列所能处理的平均数连续到达时,此策略允许无界线程具有增长的可能性

c、有界队列。当使用有限的 maximumPoolSizes 时有界队列(如 ArrayBlockingQueue)有助于防止资源耗尽,但是可能较难调整和控制队列大小和最大池大小可能需要相互折衷:使用夶型队列和小型池可以最大限度地降低 CPU 使用率、操作系统资源和上下文切换开销,但是可能导致人工降低吞吐量如果任务频繁阻塞(例洳,如果它们是 I/O 边界)则系统可能为超过您许可的更多线程安排时间。使用小型队列通常要求较大的池大小CPU 使用率较高,但是可能遇箌不可接受的调度开销这样也会降低吞吐量。

在 ThreadPoolExecutor.DiscardOldestPolicy 中如果执行程序尚未关闭,则位于工作队列头部的任务将被删除然后重试执行程序(如果再次失败,则重复此过程)

定义和使用其他种类的 RejectedExecutionHandler 类也是可能的,但这样做需要非常小心尤其是当策略仅用于特定容量或排队筞略时。

ThreadLocal、搜集统计信息或添加日志条目此外,还可以重写方法terminated() 来执行 Executor 完全终止后需要完成的所有特殊处理

如果挂钩或回调方法抛出異常,则内部辅助线程将依次失败并突然终止

方法 getQueue() 允许出于监控和调试目的而访问工作队列。强烈反对出于其他任何目的而使用此方法remove(java.lang.Runnable) 和purge() 这两种方法可用于在取消大量已排队任务时帮助进行存储回收。

我要回帖

更多关于 线程池和队列 的文章

 

随机推荐