先来看一下构造函数

     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的更多相关文章

  1. 四、Android学习第四天——JAVA基础回顾(转)

    (转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 四.Android学习第四天——JAVA基础回顾 这才学习Android的 ...

  2. 【Spring学习】【Java基础回顾-数据类型】

    Java基础回顾过程中,之前对于Java相关基础知识都是从这个人的博客看一些,那边的内容看一下,觉得不够系统化,决定用xmind脑图的形式,将Java基础知识回顾的作为一个系列,当前正在做的会包含: ...

  3. Java基础回顾_第二部分_Java流程控制

    Java基础回顾_第二部分 Java流程控制 Scanner对象(扫描器,捕获输入) import java.util.Scanner; public class Demo01 { public st ...

  4. Java基础回顾_第一部分

    Java基础回顾 基本数据类型 数值类型 什么是字节? 位(bit):是计算机中数据的最小单位 字节(byte):是计算机中数据处理的基本单位,习惯上用大写字母B来表示 1 B = 8 bit 字符: ...

  5. Java实习生常规技术面试题每日十题Java基础(七)

    目录 1. Java设计模式有哪些? 2.GC是什么?为什么要有GC? 3. Java中是如何支持正则表达式. 4.比较一下Java和JavaSciprt. 5.Math.round(11.5) 等于 ...

  6. 1、java基础回顾与加强

    一.    基础回顾 1   集合 1.1  集合的类型与各自的特性 ---|Collection: 单列集合 ---|List: 有存储顺序, 可重复 ---|ArrayList:    数组实现, ...

  7. Java基础回顾

    学习基础背景:Acmer.有C/C++基础 以[Java语言程序设计(基础篇)]第10版为参考(感谢YJJ的推荐),列出部分知识点,注意思考背后的原因和好处坏处. [14-16章——关于可视化编程的章 ...

  8. java基础回顾(2)

    java中只有两种类型:基础类型.引用类型 8中基本类型:byte  short int long float double char boolean,其中byte类型取值范围[-2^7~2^7-1] ...

  9. java基础回顾之IO

    Java的IO 是Java运用重要部分之一,涉及到的内容也比较多,容易混淆,一段时间不用,可能就会遗忘,要时常回顾记忆一下: (图片来源于网络) Java 流在处理上分为字符流和字节流. 字符流处理的 ...

随机推荐

  1. SecureCRT控制台显示中文字符的设置

  2. C和C++混合编程

    extern "C"表示编译生成的内部符号名使用C约定.C++支持函数重载,而C不支持,两者的编译规则也不一样.函数被C++编译后在符号库中的名字与C语言的不 同.例如,假设某个函 ...

  3. c# 对话框交换数据

    本例是一个管理联系人信息的小程序,程序有两个窗体,一个主窗体,在listview控件中显示联系人信息列表,一个对话框窗体,用来显示和修改 某个联系人的信息.通过主窗体的菜单命令,可以打开对话框,并把主 ...

  4. python(8) 自己制造异常让程序退出,把print的内容写入到文件

    异常 也可以自己输出异常原因: raise Exception("404 404 404") import math import time #print 到文件的代码****** ...

  5. RPM软件包制作

    参考网站:How to create an RPM package/zh-cn[教程]https://fedoraproject.org/wiki/How_to_create_an_RPM_packa ...

  6. Haproxy安装及配置(转)

    1.安装 # wget http://haproxy.1wt.eu/download/1.3/src/haproxy-1.3.20.tar.gz # tar zcvf haproxy-1.3.20.t ...

  7. java小程序 示例 菲薄垃圾数列

    package com.test; import java.util.Scanner; import org.junit.Test; import com.sun.xml.internal.ws.ap ...

  8. js解析或获取页面路径归纳

    /** * 当填写参数href后,解析你给的参数,如果为空自动从获取浏览器的地址 *测试路径:>>>http://127.0.0.1:8020/url/index.html?id=1 ...

  9. jQuery制作图片的等比例缩放

    1资料的排版 2.html代码 <body> <div class="BB"><img src="dw.jpg" alt=&quo ...

  10. inno setup 执行SQL

    参考之:1.可将导入数据的功能写入一个小程序,再外部调用(楼上已经说了):2.可用程序代码:[Setup] AppName=科發醫院管理系統 AppVerName=科發醫院管理系統4.0 AppPub ...