更新时间:
#ThreadPoolExecutor线程池技术
java是一门多线程的语言,基本上生产环境的Java项目都离不开多线程。而线程则是其中最重要的系统资源之一,如果这个资源利用得不好,很容易导致程序低效率,甚至是出问题。有以下场景,有个电话拨打系统,有一堆需要拨打的任务要执行,首先肯定是考虑多线程异步去执行。假如我每执行一个拨打任务都new一个Thread去执行,当同时有1万个任务需要执行的时候,那么就会新建1万个线程,加上线程各种初始销毁等操作,这个消耗是巨大的。而其实往往实现这些功能的时候,并不是完全需要实时马上完成,只是希望在可控范围内尽量提高执行的并发性能。因此线程池技术应用而生,Java中最常用的线程池技术就是ThreadPoolExecutor。接下来就整体看看ThreadPoolExecutor的实现。这个类的注解非常多,很多也是重点,所以就不从注解开始看起。先从使用说起,有个概念先。
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}
定义好一些必要的参数,构建一个ThreadPoolExecutor对象。然后调用对象的execute()方法即可。参数说明:
- corePoolSize,线程池保留的最小线程数。如果线程池中的线程少于此数目,则在执行execut()时创建。
- maximumPoolSize,线程池中允许拥有的最大线程数。
- keepAliveTime、unit,当线程闲置时,保持线程存活的时间。
- workQueue,工作队列,存放提交的等待任务,其中有队列大小的限制。
#策略
AbortPolicy:丢弃任务,抛出 RejectedExecutionException CallerRunsPolicy:只用调用者所在线程来运行任务,有反馈机制,使任务提交的速度变慢)。 DiscardOldestPolicy 若没有发生shutdown,尝试丢弃队列里最近的一个任务,并执行当前任务, 丢弃任务缓存队列中最老的任务,并且尝试重新提交新的任务 DiscardPolicy:不处理,丢弃掉, 拒绝执行,不抛异常 当然,也可以根据应用场景需要来实现RejectedExecutionHandler接口自定义策略.如记录日志或持久化存储不能处理的任务