java基础回顾(七)——ThreadPoolExecutor
先来看一下构造函数
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
重点讲解:
1、当线程池小于corePoolSize时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程。
2、当线程池达到corePoolSize时,新提交任务将被放入workQueue中,等待线程池中任务调度执行
3、当workQueue已满,且maximumPoolSize>corePoolSize时,新提交任务会创建新线程执行任务
4、当提交任务数超过maximumPoolSize时,新提交任务由RejectedExecutionHandler处理
5、当线程池中超过corePoolSize线程,空闲时间达到keepAliveTime时,关闭空闲线程
6、当设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize线程空闲时间达到keepAliveTime也将关闭

配置方案:
1、构造一个固定线程数目的线程池,配置的corePoolSize与maximumPoolSize大小相同,同时使用了一个无界LinkedBlockingQueue存放阻塞任务,因此多余的任务将存在再阻塞队列,不会由RejectedExecutionHandler处理
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
2、构造一个缓冲功能的线程池,配置corePoolSize=0,maximumPoolSize=Integer.MAX_VALUE,keepAliveTime=60s,以及一个无容量的阻塞队列 SynchronousQueue,因此任务提交之后,将会创建新的线程执行;线程空闲超过60s将会销毁
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
3、构造一个只支持一个线程的线程池,配置corePoolSize=maximumPoolSize=1,无界阻塞队列LinkedBlockingQueue;保证任务由一个线程串行执行
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
4、构造有定时功能的线程池,配置corePoolSize,无界延迟阻塞队列DelayedWorkQueue;有意思的是:maximumPoolSize=Integer.MAX_VALUE,由于DelayedWorkQueue是无界队列,所以这个值是没有意义的
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}
public ScheduledThreadPoolExecutor(int corePoolSize,
ThreadFactory threadFactory) {
super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
new DelayedWorkQueue(), threadFactory);
}
总结:
1、用ThreadPoolExecutor自定义线程池,看线程是的用途,如果任务量不大,可以用无界队列,如果任务量非常大,要用有界队列,防止OOM
2、如果任务量很大,还要求每个任务都处理成功,要对提交的任务进行阻塞提交,重写拒绝机制,改为阻塞提交。保证不抛弃一个任务
3、最大线程数一般设为2N+1最好,N是CPU核数
4、核心线程数,看应用,如果是任务,一天跑一次,设置为0,合适,因为跑完就停掉了,如果是常用线程池,看任务量,是保留一个核心还是几个核心线程数
5、如果要获取任务执行结果,用CompletionService,但是注意,获取任务的结果的要重新开一个线程获取,如果在主线程获取,就要等任务都提交后才获取,就会阻塞大量任务结果,队列过大OOM,所以最好异步开个线程获取结果
java基础回顾(七)——ThreadPoolExecutor的更多相关文章
- 四、Android学习第四天——JAVA基础回顾(转)
(转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 四.Android学习第四天——JAVA基础回顾 这才学习Android的 ...
- 【Spring学习】【Java基础回顾-数据类型】
Java基础回顾过程中,之前对于Java相关基础知识都是从这个人的博客看一些,那边的内容看一下,觉得不够系统化,决定用xmind脑图的形式,将Java基础知识回顾的作为一个系列,当前正在做的会包含: ...
- Java基础回顾_第二部分_Java流程控制
Java基础回顾_第二部分 Java流程控制 Scanner对象(扫描器,捕获输入) import java.util.Scanner; public class Demo01 { public st ...
- Java基础回顾_第一部分
Java基础回顾 基本数据类型 数值类型 什么是字节? 位(bit):是计算机中数据的最小单位 字节(byte):是计算机中数据处理的基本单位,习惯上用大写字母B来表示 1 B = 8 bit 字符: ...
- Java实习生常规技术面试题每日十题Java基础(七)
目录 1. Java设计模式有哪些? 2.GC是什么?为什么要有GC? 3. Java中是如何支持正则表达式. 4.比较一下Java和JavaSciprt. 5.Math.round(11.5) 等于 ...
- 1、java基础回顾与加强
一. 基础回顾 1 集合 1.1 集合的类型与各自的特性 ---|Collection: 单列集合 ---|List: 有存储顺序, 可重复 ---|ArrayList: 数组实现, ...
- Java基础回顾
学习基础背景:Acmer.有C/C++基础 以[Java语言程序设计(基础篇)]第10版为参考(感谢YJJ的推荐),列出部分知识点,注意思考背后的原因和好处坏处. [14-16章——关于可视化编程的章 ...
- java基础回顾(2)
java中只有两种类型:基础类型.引用类型 8中基本类型:byte short int long float double char boolean,其中byte类型取值范围[-2^7~2^7-1] ...
- java基础回顾之IO
Java的IO 是Java运用重要部分之一,涉及到的内容也比较多,容易混淆,一段时间不用,可能就会遗忘,要时常回顾记忆一下: (图片来源于网络) Java 流在处理上分为字符流和字节流. 字符流处理的 ...
随机推荐
- 3. c的输入输出
putchar与getchar操作输入输出通道 #include <stdio.h> #include <ctype.h> main(){ int c; while((c = ...
- iphone Dev 开发实例10:How To Add a Slide-out Sidebar Menu in Your Apps
Creating the Xcode Project With a basic idea about what we’ll build, let’s move on. You can create t ...
- ADF_General JSF系列1_创建一个简单的JSF Application
2015-02-17 Creatd By BaoXinjian
- Oracle11G登录时提示:ORA-12557: TNS:协议适配器不可加载
原文 Oracle11G登录时提示:ORA-12557: TNS:协议适配器不可加载 初步分析是ORACLE_HOME设置错误引起的.前几天不小心看到系统环境变量中的其值为空,就手贱的加载了一个ora ...
- 非spring组件servlet、filter、interceptor中注入spring bean
问题:在filter和interceptor中经常需要调用Spring的bean,filter也是配置在web.xml中的,请问一下这样调用的话,filter中调用Spring的某个bean,这个be ...
- Jquery Validation 插件验证手机号
自定义手机号验证代码 http://www.2cto.com/kf/201505/402781.html // 手机号码验证 jQuery.validator.addMethod("isM ...
- iOS 数字字符串的直接运算 + - * /
NSDecimalNumber *d1 = [NSDecimalNumber decimalNumberWithString:@"3.14"]; NSDecimalNumber * ...
- Python进阶02 文本文件的输入输出
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! Python具有基本的文本文件读写功能.Python的标准库提供有更丰富的读写功能 ...
- 如何让python程序运行得更快
原则1:不优化 原则2:不要优化那些不重要的部分(否则会降低可读性) 解决方案: 1. 使用函数,局部变量比全局变量快很多.尽量使用函数,如main() 2. 有选择性的消除属性访问. 如多用 fro ...
- C++primer 练习13.39
13.39 编写你自己版本的StrVec,包括自己版本的reserve,capacity(参见9.4节,第318页)和resize(参见9.3.5节,第314页) 13.40 为你的StrVec类添加 ...