赞
踩
Java中的ThreadPoolExecutor, 一般使用时直接利用现有的构造工具java.util.concurrent.Executors 直接构造使用, 但是在数据量任务数较多,或者想控制任务执行的时候, 会有一些不方便.
使用ThreadPoolExecutor直接构造我们需要的线程池, 以构造函数
- public ThreadPoolExecutor(int corePoolSize,
- int maximumPoolSize,
- long keepAliveTime,
- TimeUnit unit,
- BlockingQueue<Runnable> workQueue,
- RejectedExecutionHandler handler) {
- this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
- Executors.defaultThreadFactory(), handler);
- }
为例,
corePoolSize: 指定核心线程池大小, 需要注意的是, 构造完成后的线程池, 在未接收到任务时, 线程数为0.
maximumPoolSize: 线程池的最大同时工作线程数, 是否真正生效和后面的workQueue参数设定有直接关系
keepAliveTime: 线程池中 maximumPoolSize减去 corePoolSize的线程在空闲时间的生存时间, 多余改时间将被销毁.
unit: 空闲线程的销毁时间的时间单位
workQueue: 线程池添加的任务在线程池中工作线程数量达到最大设定值后的唯一去处, 未达到最大数量时, 会生成新的工作线程接受任务.
handler: 这个是拒绝策略,后面说.
以如下设置为例:
- LinkedBlockingQueue<Runnable> blockingQueue = new LinkedBlockingQueue<Runnable>(16);
- ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 100,
- 20, TimeUnit.MILLISECONDS, blockingQueue,new ThreadPoolExecutor.CallerRunsPolicy());
构造最大容量为16的queue, 构造核心为2, 最大为100, 最长空闲时间为20ms, 以ThreadPoolExecutor.CallerRunsPolicy为拒绝策略的线程池.
假设现在有18个任务同时放到该线程池中, 每个任务执行时间为2s, 那么执行完大概需要多久?
是的, 需要18s, 因为核心工作线程为2, 同时执行两个任务, 共18个, 需要执行9组, 每组2s, 共计18s, 电脑实际耗时为 18005ms.
假设现在有100个任务, 需要多久?
小于18s, 因为线程池首先接收到的任务, 构造了两个核心工作线程, 紧接着的16个放到queue中, 接下来的task由于queue已满, 故需要根据maximumPoolSize 扩展线程池中的工作线程, 本例中上限为100, 故可以扩展98个工作线程, 现有82个task需要加入, 故线程池放完全部100个任务后, 是84个工作线程, 此时queue中还有16个等待任务, 故执行时间大概为4s, 我电脑实际执行为4016ms.
任务多了反而更快, 是因为线程池中的工作线程扩展了, 干活的多了.
我们线程池最大能容纳120个任务,如果我们添加130个任务, 根据我们的拒绝策略, 在线程池未关闭的情况下,将有我们的主线程执行, ThreadPoolExecutor 默认是拒绝新的任务加入.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。