线程池——ThreadPoolExecutor
1.构造方法
ThreadPoolExecutor pool=new ThreadPoolExecutor(
2
,5
,5000
,TimeUnit.MILLISECONDS
,new LinkedBlockingQueue<Runnable>()
,Executors.defaultThreadFactory()
,new ThreadPoolExecutor.AbortPolicy());
1.1.参数说明
序号 | 名称 | 类型 | 说明 |
---|
1 | corePoolSize | int | 核心线程池大小 |
2 | maximumPoolSize | int | 最大线程池大小 |
3 | keepAliveTime | long | 空闲线程最大空闲时间(超过corePoolSize的线程) |
4 | unit | TimeUnit | keepAliveTime的时间单位 |
5 | workQueue | BlockingQueue | 线程等待队列 |
6 | threadFactory | ThreadFactory | 线程创建工厂 |
7 | handler | RejectedExecutionHandler | 拒绝策略 |
线程大小设置
- 获取核心线程数:int Ncpu=Runtime.getRuntime().availableProcessors();
- CPU密集型(该任务需要大量的运算,而没有阻塞,CPU一直全速运行):Ncpu+1
- IO密集型:1.不是一直在执行:2Ncpu; 2.需要大量的IO,即大量的阻塞: Ncpu((cpu执行时间+io阻塞时间)/cpu执行时间)
1.2.workQueue(线程等待队列)
序号 | 名称 | 类型 | 说明 |
---|
1 | 直接提交队列 | SynchronousQueue | 提交的任务不会被保存,总是会提交执行,每次执行插入操作就会阻塞,需要再执行删除操作才会被唤醒,反之每个删除操作也都要等待对应的插入操作;当创建的线程数大于maximumPoolSize时,执行拒绝策略 |
2 | 有界任务队列 | ArrayBlockingQueue | 新的任务需要执行时,线程池会创建新的线程,直到创建的线程数量达到corePoolSize时,则会将新的任务加入到等待队列中。若等待队列已满,即超过ArrayBlockingQueue初始化的容量,则继续创建线程,直到线程数量达到maximumPoolSize设置的最大线程数量,若大于maximumPoolSize,则执行拒绝策略 |
3 | 无界任务队列 | LinkedBlockingQueue | 任务队列可以无限制的添加新的任务,而线程池创建的最大线程数量就是你corePoolSize设置的数量,相当于设置的maximumPoolSize参数是无效的,哪怕你的任务队列中缓存了很多未执行的任务,当线程池的线程数达到corePoolSize后,就不会再增加了;若后续有新的任务加入,则直接进入队列等待;特别注意防止资源耗尽 |
4 | 优先任务队列 | PriorityBlockingQueue | 任务按照优先级进行排序,然后按顺序执行;是一个特殊的无界任务队列 |
1.3.handler(拒绝策略)
序号 | 类型 | 说明 |
---|
1 | AbortPolicy | 直接抛出异常,阻止后续运行 |
2 | CallerRunsPolicy | 如果线程池的线程数量达到上限,该策略会把任务队列中的任务放在调用者线程当中运行 |
3 | DiscardOledestPolicy | 丢弃任务队列中最老的一个任务,也就是当前任务队列中最先被添加进去的,马上要被执行的那个任务,并尝试再次提交 |
4 | DiscardPolicy | 丢弃无法处理的任务,不做任何处理 |
2.线程提交
2.1.excute()
pool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getId());
}
});
2.2.submit()
Future<Object> f = pool.submit(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getId());
}
});
Object o = f.get();
if (null == o) {
System.out.println("未返回结果...");
} else {
System.out.println("执行完毕,已返回结果:"+o);
}