构造方法

ThreadPoolExecutor共4个构造方法:

直接看参数最多的7个参数分别代表:

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,  TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
  • corePoolSize: 线程池核心线程数
  • maximumPoolSize:线程池最大数
  • keepAliveTime: 空闲线程存活时间
  • unit: 时间单位
  • workQueue: 线程池所使用的缓冲队列
  • threadFactory:线程池创建线程使用的工厂
  • handler: 线程池对拒绝任务的处理策略
  • RejectedExecutionHandler来处理;ThreadPoolExecutor内部有实现4个拒绝策略,默认为AbortPolicy策略:

    • CallerRunsPolicy:由调用execute方法提交任务的线程来执行这个任务
    • AbortPolicy:抛出异常RejectedExecutionException拒绝提交任务
    • DiscardPolicy:直接抛弃任务,不做任何处理
    • DiscardOldestPolicy:去除任务队列中的第一个任务,重新提交

1.当池中正在运行的线程数(包括空闲线程数)小于corePoolSize时,新建线程执行任务

 public static void main(String[] args) {
ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 3, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1));
// 任务1
pool.execute(() -> {
try {
Thread.sleep(3 * 1000);
System.out.println("--helloWorld_001--" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
});
//任务2
pool.execute(() -> System.out.println("--helloWorld_002--" + Thread.currentThread().getName()));
}

结论:线程1 结束后 没有继续线程1 而是启动线程2

2.当池中正在运行的线程数(包括空闲线程数)大于等于corePoolSize时,新插入的任务进入workQueue排队(如果workQueue长度允许),等待空闲线程来执行。

    public static void main(String[] args) {
ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 3, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1));
// 任务1
pool.execute(() -> {
try {
Thread.sleep(3 * 1000);
System.out.println("--helloWorld_001--" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// 任务2
pool.execute(() -> {
try {
Thread.sleep(5 * 1000);
System.out.println("--helloWorld_002--" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// 任务3
pool.execute(() -> System.out.println("--helloWorld_003--" + Thread.currentThread().getName()));
}

结论:任务2在运行过程中,任务3启动不会新建线程,因为有一个队列是空的,maximumPoolSize=3这个参数不起作用。

3.当队列里的任务达到上限,并且池中正在进行的线程小于maxinumPoolSize,对于新加入的任务,新建线程。

 public static void main(String[] args) {
ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 3, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1));
// 任务1
pool.execute(() -> {
try {
Thread.sleep(3 * 1000);
System.out.println("--helloWorld_001--" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// 任务2
pool.execute(() -> {
try {
Thread.sleep(5 * 1000);
System.out.println("--helloWorld_002--" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// 任务3
pool.execute(() -> System.out.println("--helloWorld_003--" + Thread.currentThread().getName()));
// 任务4
pool.execute(() -> System.out.println("--helloWorld_004--" + Thread.currentThread().getName()));
}

结果:任务1,2启动后 任务3在队列 ,队列就满了,由于正在进行的线程数是2<maximumPoolSize,只能新建一个线程了 然后任务4就进了新线程-3,任务4结束,队列里的任务3在线程3 进行。

4.队列里的任务达到上限,并且池中正在运行的线程等于maximumPoolSize,对于新加入的任务,执行拒绝策略(线程池默认的策略是抛异常)。

public static void main(String[] args) {
ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 3, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1));
// 任务1
pool.execute(() -> {
try {
Thread.sleep(3 * 1000);
System.out.println("--helloWorld_001--" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// 任务2
pool.execute(() -> {
try {
Thread.sleep(5 * 1000);
System.out.println("--helloWorld_002--" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// 任务3
pool.execute(() -> System.out.println("--helloWorld_003--" + Thread.currentThread().getName()));
// 任务4
pool.execute(() -> {
try {
Thread.sleep(2 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("--helloWorld_004--" + Thread.currentThread().getName());
});
// 任务5
pool.execute(() -> System.out.println("--helloWorld_005--" + Thread.currentThread().getName()));
}
运行结果:
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task ExecutorDemo$$Lambda$5/999966131@7699a589 rejected from java.util.concurrent.ThreadPoolExecutor@58372a00[Running, pool size = 3, active threads = 3, queued tasks = 1, completed tasks = 0]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)
at ExecutorDemo.main(ExecutorDemo.java:40)
--helloWorld_004----pool-1-thread-3
--helloWorld_003--pool-1-thread-3
--helloWorld_001--pool-1-thread-1
--helloWorld_002--pool-1-thread-2

结论:队列达到上限,线程池达到最大值,故抛出异常。

关闭线程

  分为两种方式:

pool.shutdown();//平缓关闭,不允许新的线程加入,正在运行的都跑完即可关闭。
pool.shutdownNow();//暴力关闭。不允许新的线程加入,且直接停到正在进行的线程。

ThreadPoolExecutor使用方法的更多相关文章

  1. 12.ThreadPoolExecutor线程池原理及其execute方法

    jdk1.7.0_79  对于线程池大部分人可能会用,也知道为什么用.无非就是任务需要异步执行,再者就是线程需要统一管理起来.对于从线程池中获取线程,大部分人可能只知道,我现在需要一个线程来执行一个任 ...

  2. ThreadPoolExecutor机制探索-我们到底能走多远系列(41)

    我们到底能走多远系列(41) 扯淡: 这一年过的不匆忙,也颇多感受,成长的路上难免弯路,这个世界上没人关心你有没有变强,只有自己时刻提醒自己,不要忘记最初出发的原因. 其实这个世界上比我们聪明的人无数 ...

  3. java线程API学习 线程池ThreadPoolExecutor(转)

    线程池ThreadPoolExecutor继承自ExecutorService.是jdk1.5加入的新特性,将提交执行的任务在内部线程池中的可用线程中执行. 构造函数 ThreadPoolExecut ...

  4. 《java.util.concurrent 包源码阅读》12 线程池系列之ThreadPoolExecutor 第二部分

    接着说worker线程是如何工作的.ThreadPoolExecutor有一个成员类叫Worker,所起到的作用就是线程池worker线程的作用. private final class Worker ...

  5. JAVA线程池学习,ThreadPoolTaskExecutor和ThreadPoolExecutor有何区别?

    初学者很容易看错,如果没有看到spring或者JUC源码的人肯定是不太了解的. ThreadPoolTaskExecutor是spring core包中的,而ThreadPoolExecutor是JD ...

  6. 自定义 ThreadPoolExecutor 处理线程运行时异常

    自定义 ThreadPoolExecutor 处理线程运行时异常 最近看完了ElasticSearch线程池模块的源码,感触颇深,然后也自不量力地借鉴ES的 EsThreadPoolExecutor ...

  7. java内置线程池ThreadPoolExecutor源码学习记录

    背景 公司业务性能优化,使用java自带的Executors.newFixedThreadPool()方法生成线程池.但是其内部定义的LinkedBlockingQueue容量是Integer.MAX ...

  8. Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理

    相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...

  9. 多线程相关-ThreadPoolExecutor

    应用层面: ThreadPoolExecutor: 创建多线程池执行器:new ThreadPoolExecutor(),创建方法最终都是走的以下这个构造方法: /** * Creates a new ...

随机推荐

  1. JAVA数据处理的常用技术

    背景 在实际开发中,数据的处理有五种:获取.传输.存储.分析.转换.每种各对应一些常用的技术. 序列化和反序列化 序列化是将对象的信息转换为可传输或可存储形式的过程.反序列化就是反过来让这些可传输的. ...

  2. Hibernate4之JPA规范配置详解

    @Table Table用来定义entity主表的name,catalog,schema等属性. 属性说明: name:表名 catalog:对应关系数据库中的catalog schema:对应关系数 ...

  3. JDK 13 都已经发布了,Java 8 依然是最爱

    在 JDK 版本的世界里,从来都是 Oracle 发他的新版本,我们继续用我们的老版本.三年之前用 JDK 7,后来终于升级到了 JDK 8.自从升级了没多久,JDK 就开始了半年发一个新版本的节奏, ...

  4. Django之choices选项和富文本编辑器的使用

    项目准备 1.创建数据库 create database choices_test default charset utf8; 2.创建一个名为 choices_test 的Django项目: 3.创 ...

  5. vuex(vue状态管理)

    vuex(vue状态管理) 1.先安装vuex npm install vuex --save   2.在项目的src目录下创建store目录,并且新建index.js文件,然后创建vuex实例,引入 ...

  6. Python学习笔记整理总结【Django】:Model操作(二)

    1.操作汇总 # 增 # # models.Tb1.objects.create(c1='xx', c2='oo') 增加一条数据,可以接受字典类型数据 **kwargs # obj = models ...

  7. Spring 梳理 - filter、interceptor、aop实现与区别 -第一篇

    前言 项目中我们经常需要对RESTful api进行拦截,主流实现方法有filter.interceptor.aop,先说一下他们各自的实现. Filter AnimalFilter实现javax.s ...

  8. Flask基础(05)-->路由的基本定义

    # 导入Flask from flask import Flask # 创建Flask的应用程序 app = Flask(__name__) # http://127.0.0.1:5000/123或者 ...

  9. 蓝松短视频SDK基本功能免费列表

    下载地址:https://github.com/LanSoSdk/LanSoEditor_common 功能免费. 个人和公司都可以商用,不需要和我们说明. 直接下载, 直接去用既可. 完全不需要和我 ...

  10. MongoDB的复制源oplog

    ​ 之前有说过MongoDB的复制是异步复制的,其实也就是通过oplog来实现的,他存放在local数据库中,我们来查询一下主节点的日志大小. ​ 除了主节点有oplog之外,其他节点也就有oplog ...