一、使用Executors创建线程池

之前创建线程的时候都是用的Executors的newFixedThreadPool(),newSingleThreadExecutor(),newCachedThreadPool()这三个方法。当然Executors也是用不同的参数去new ThreadPoolExecutor

1. newFixedThreadPool()

创建线程数固定大小的线程池。 由于使用了LinkedBlockingQueue所以maximumPoolSize 没用,当corePoolSize满了之后就加入到LinkedBlockingQueue队列中。每当某个线程执行完成之后就从LinkedBlockingQueue队列中取一个。所以这个是创建固定大小的线程池。

public static ExecutorService newFixedThreadPool(int nThreads) {

return new ThreadPoolExecutor(nThreads, nThreads,

0L, TimeUnit.MILLISECONDS,

new LinkedBlockingQueue());

}

public ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueue workQueue) {

this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,

Executors.defaultThreadFactory(), defaultHandler);

}

2.newSingleThreadPool()

创建线程数为1的线程池,由于使用了LinkedBlockingQueue所以maximumPoolSize 没用,corePoolSize为1表示线程数大小为1,满了就放入队列中,执行完了就从队列取一个。

public static ExecutorService newSingleThreadExecutor() {

return new FinalizableDelegatedExecutorService

(new ThreadPoolExecutor(1, 1,

0L, TimeUnit.MILLISECONDS,

new LinkedBlockingQueue()));

}

3.newCachedThreadPool()

创建可缓冲的线程池。没有大小限制。由于corePoolSize为0所以任务会放入SynchronousQueue队列中,SynchronousQueue只能存放大小为1,所以会立刻新起线程,由于maxumumPoolSize为Integer.MAX_VALUE所以可以认为大小为2147483647。受内存大小限制。

public static ExecutorService newCachedThreadPool() {

return new ThreadPoolExecutor(0, Integer.MAX_VALUE,

60L, TimeUnit.SECONDS,

new SynchronousQueue());

}

public ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueue workQueue) {

this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,

Executors.defaultThreadFactory(), defaultHandler);

}

二、使用ThreadPoolExecutor创建线程池

ThreadPoolExecutor的构造函数

public ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueue workQueue,

ThreadFactory threadFactory,

RejectedExecutionHandler handler) {

if (corePoolSize

maximumPoolSize <= 0 ||

maximumPoolSize

keepAliveTime

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、maximumPoolSize 最大线程数, 当线程数 >= corePoolSize的时候,会把runnable放入workQueue中

3、keepAliveTime  保持存活时间,当线程数大于corePoolSize的空闲线程能保持的最大时间。

4、unit 时间单位

5、workQueue 保存任务的阻塞队列

6、threadFactory 创建线程的工厂

7、handler 拒绝策略

任务执行顺序:

1、当线程数小于corePoolSize时,创建线程执行任务。

2、当线程数大于等于corePoolSize并且workQueue没有满时,放入workQueue中

3、线程数大于等于corePoolSize并且当workQueue满时,新任务新建线程运行,线程总数要小于maximumPoolSize

4、当线程总数等于maximumPoolSize并且workQueue满了的时候执行handler的rejectedExecution。也就是拒绝策略。

ThreadPoolExecutor默认有四个拒绝策略:

1、ThreadPoolExecutor.AbortPolicy()   直接抛出异常RejectedExecutionException

2、ThreadPoolExecutor.CallerRunsPolicy()    直接调用run方法并且阻塞执行

3、ThreadPoolExecutor.DiscardPolicy()   直接丢弃后来的任务

4、ThreadPoolExecutor.DiscardOldestPolicy()  丢弃在队列中队首的任务

当然可以自己继承RejectedExecutionHandler来写拒绝策略.

int corePoolSize = 1;

int maximumPoolSize = 2;

int keepAliveTime = 10;

//BlockingQueue workQueue = new LinkedBlockingQueue();

BlockingQueue workQueue = new ArrayBlockingQueue(5);

ThreadFactory threadFactory = Executors.defaultThreadFactory();

//线程池和队列满了之后的处理方式

//1.跑出异常

RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();

RejectedExecutionHandler handler2 = new ThreadPoolExecutor.CallerRunsPolicy();

RejectedExecutionHandler handler3 = new ThreadPoolExecutor.DiscardPolicy();

RejectedExecutionHandler handler4 = new ThreadPoolExecutor.DiscardOldestPolicy();

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, threadFactory, handler2);

for (int j = 1; j

threadPoolExecutor.execute(new Runnable() {

public void run() {

try {

System.out.println(Thread.currentThread().getName());

TimeUnit.SECONDS.sleep(1);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

});

}

System.out.println(threadPoolExecutor);

}

java excutorthread_Java中ThreadPoolExecutor的参数理解相关推荐

  1. Java中ThreadPoolExecutor的参数理解

    一.使用Executors创建线程池 之前创建线程的时候都是用的Executors的newFixedThreadPool(),newSingleThreadExecutor(),newCachedTh ...

  2. java shareable_spring中@Resource和@Autowired理解详解_编程语言_IT虾米网

    @Resource在bean注入的时候使用,@Resource所属包其实不是spring,而是javax.annotation.Resource,只不过spring支持该注解 @Resource里有n ...

  3. java笔记(自学java过程中遇到的不理解的地方)qvq

    1.单引号和双引号以及char和String的区别 单引号引的数据 是char类型的,双引号引的数据 是String类型的:char定义时用单引号,只能有一个字母,数字.char c='c'; 而St ...

  4. Java方法中的参数太多,第8部分:工具

    在我的系列文章的前七篇文章中,有关处理Java方法中期望的参数过多的内容集中在减少方法或构造函数期望的参数数量的替代方法上. 在本系列的第八篇文章中,我将介绍一些工具,这些工具可帮助您确定可能存在过多 ...

  5. 解惑(三)----- 深入理解Python中的self参数和__init__(self)方法--通过类比Java语言

    一.前言 在这里我想通过用Python和Java语言的类比来对Python中的self参数和__init__(self)方法做一个深入的解释.这样可以加深对self参数和__init__(self)方 ...

  6. JDK1.5中的线程池(java.util.concurrent.ThreadPoolExecutor

    http://www.diybl.com/course/3_program/java/javajs/200797/70003.html 在多线程大师Doug Lea的贡献下,在JDK1.5中加入了许多 ...

  7. Java方法中的参数太多,第4部分:重载

    期望将过多的参数传递给Java方法的问题之一是,该方法的客户端很难确定它们是否以适当的顺序传递了适当的值. 在以前的文章中,我描述了如何使用自定义类型 , 参数对象和构建器来解决此问题. 解决此问题的 ...

  8. Java方法中的参数太多,第5部分:方法命名

    在上一篇文章 (有关处理Java方法中过多参数的系列文章的 第4部分 )中,我将方法重载视为一种向客户提供需要较少参数的方法版本或构造函数的方法. 我描述了该方法的一些缺点,并建议从方法重载中摆脱出来 ...

  9. Java方法中的参数太多,第7部分:可变状态

    在我的系列文章的第七篇中,有关解决Java方法或构造函数中过多参数的问题 ,我着眼于使用状态来减少传递参数的需要. 我等到本系列的第七篇文章来解决这个问题的原因之一是,它是我最不喜欢的减少传递给方法和 ...

最新文章

  1. Find Code for Research Papers
  2. Shallow and retained sizes
  3. Vue CLI 安装
  4. z-index无效注意事项
  5. RESTful架构与RPC架构
  6. 代数学笔记5: 群论(一)
  7. pythonapi异步_Python-FastAPI异步博客开发记录--异步篇
  8. spark Application report for application_1498032012194_0036 (state: FAILED)
  9. 语音网关典型配置实例
  10. vscode风格超酷个人主页源码
  11. EXCEL下拉菜单怎么弄
  12. 安装Go语言开发工具
  13. matlab 正态分布分位点,为标准正态分布的上a分位点.PPT
  14. 智能问答机器人python_帮帮智能问答机器人中TaskBot任务对话算法实践
  15. 移动端应用视频小程序加密播放(存档)
  16. java中getTime()
  17. GPS从入门到放弃(三)、GPS坐标系
  18. 依托抖音、快手直播的上架工具开发
  19. Add User for Power Apps 给PowerApps 添加账号
  20. Detours学习之十三:Detours API用于将dll和有效负载插入新进程的api

热门文章

  1. iPhone内存管理基本原则
  2. 安装配置libmemcached
  3. .NET6 新功能和新生态
  4. 【全】.net core平台单元/集成测试结果、覆盖率、圈复杂度到可视化HTML报告之路...
  5. 自主生态再进一步,龙芯中科完成.NET3.1-LoongArch64平台研发
  6. 多语言应用开发中本地化信息对照表
  7. 面向.NET开发人员的Dapr——发布和订阅
  8. 在非容器(集群)环境下运行dapr
  9. 腾讯招.NET要求以下几点,你准备好了吗?
  10. IO 模型知多少 | 代码篇