所属包:

java.util.concurrent.ThreadPoolExecutor

类关系:

public class ThreadPoolExecutor extends AbstractExecutorService

1. 继承关系

ThreadPoolExecutor 继承了一个抽象类:AbstractExecutorService

public abstract class AbstractExecutorService implements ExecutorService

而这个AbstractExecutorService实现了一个接口:ExecutorService

public interface ExecutorService extends Executor

这个ExecutorService接口又继承了一个类:Executor

public interface Executor

可以看出:

Executor是一个顶层接口,它的子接口ExecutorService继承了它(其实还有一个子接口: ScheduledExecutorService),抽象类AbstractExecutorService实现了这个子接口ExecutorService,最终ThreadPoolExecutor 继承了抽象类AbstractExecutorService并且同时实现了子接口ExecutorService。

2. 构造方法

最简单的一个构造方法:

    /**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters and default thread factory and rejected execution handler.
* It may be more convenient to use one of the {@link Executors} factory
* methods instead of this general purpose constructor.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
* @throws IllegalArgumentException if one of the following holds:<br>
* {@code corePoolSize < 0}<br>
* {@code keepAliveTime < 0}<br>
* {@code maximumPoolSize <= 0}<br>
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue} is null
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}

有五个参数:

corePoolSize - 即使空闲时仍保留在池中的线程数,除非设置 allowCoreThreadTimeOut
maximumPoolSize - 池中允许的最大线程数
keepAliveTime - 当线程数大于核心时,这是多余的空闲线程在终止之前等待新任务的最大时间。
unit - keepAliveTime参数的时间单位
workQueue - 在执行任务之前用于保存任务的队列。 该队列将仅保存execute方法提交的Runnable任务

实际上它调用了同类的另外一个构造方法,最后两个参数用的默认值

另外一个构造方法:

    /**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
* @param threadFactory the factory to use when the executor
* creates a new thread
* @param handler the handler to use when execution is blocked
* because the thread bounds and queue capacities are reached
* @throws IllegalArgumentException if one of the following holds:<br>
* {@code corePoolSize < 0}<br>
* {@code keepAliveTime < 0}<br>
* {@code maximumPoolSize <= 0}<br>
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue}
* or {@code threadFactory} or {@code handler} is null
*/
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;
}

参数:

corePoolSize - 即使空闲时仍保留在池中的线程数,除非设置 allowCoreThreadTimeOut
maximumPoolSize - 池中允许的最大线程数
keepAliveTime - 当线程数大于内核时,这是多余的空闲线程在终止前等待新任务的最大时间。
unit - keepAliveTime参数的时间单位
workQueue - 用于在执行任务之前使用的队列。 这个队列将仅保存execute方法提交的Runnable任务。
threadFactory - 执行程序创建新线程时使用的工厂
handler - 执行被阻止时使用的处理程序,因为达到线程限制和队列容量 (拒绝策略)

3. 如何使用

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; public class MyThreadPoolExecutor { /**
* 使用有界队列:
* 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() 丢弃在队列中队首的任务
*
*
*
*/ public static void main(String[] args) { ThreadPoolExecutor pool = new ThreadPoolExecutor(
1,
2,
0L,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(3)); Runnable[] runs = new Runnable[6];
for (int i = 0; i < runs.length; i++) {
runs[i] = new MyTask(i);
} pool.execute(runs[0]); //线程1个,队列0个
pool.execute(runs[1]); //线程1个,队列1个
pool.execute(runs[2]); //线程1个,队列2个
pool.execute(runs[3]); //线程1个,队列3个
pool.execute(runs[4]); //线程2个,队列3个
pool.execute(runs[5]); //线程2个,队列3个,拒绝第六个 pool.shutdown(); }
}

线程:

public class MyTask implements Runnable {

    private int id;

    public MyTask(int id) {
this.id = id;
} @Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Task-" + id);
} }

这个就是最简单的一个使用方法了。ps:最后那个(线程1个,队列0个....)指的是,你仅仅执行runs[0];runs[0]+runs[1];runs[0]+runs[1]+runs[2];....的时候,任务被放到哪里。

但是推荐使用这种方式创建线程池:

package cn.ying.thread.pool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class MyTest { public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(5); for (int i = 0; i < 10; i++) {
pool.execute(new MyTask(i));
}
pool.shutdown();
} public void note(){
Executors.newCachedThreadPool(); //无界线程池,可以进行自动线程回收
// public static ExecutorService newCachedThreadPool() {
// return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
// 60L, TimeUnit.SECONDS,
// new SynchronousQueue<Runnable>());//SynchronousQueue:长度为1的队列
// }
Executors.newFixedThreadPool(10); //创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。
// public static ExecutorService newFixedThreadPool(int nThreads) {
// return new ThreadPoolExecutor(nThreads, nThreads,
// 0L, TimeUnit.MILLISECONDS,
// new LinkedBlockingQueue<Runnable>());
// }
Executors.newScheduledThreadPool(10); //创建一个单线程执行程序,它可安排在给定延迟后运行命令或者定期地执行
// public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
// return new ScheduledThreadPoolExecutor(corePoolSize);
// }
// public ScheduledThreadPoolExecutor(int corePoolSize) {
// super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
// new DelayedWorkQueue());
// }
Executors.newSingleThreadExecutor(); //创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程
// public static ExecutorService newSingleThreadExecutor() {
// return new FinalizableDelegatedExecutorService
// (new ThreadPoolExecutor(1, 1,
// 0L, TimeUnit.MILLISECONDS,
// new LinkedBlockingQueue<Runnable>()));
// } }
}

==============================更新

4. 拒绝策略

1. AbortPolicy(丢弃任务并抛出RejectedExecutionException异常)默认策略

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; public class Test { public static void main(String[] args) throws Exception {
ThreadPoolExecutor pool = new ThreadPoolExecutor(
1,
2,
0L,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(3),
// 拒绝并抛出异常
new ThreadPoolExecutor.AbortPolicy()); for (int i = 0; i < 6; i++){
pool.execute(new Task("任务" + i));
}
pool.shutdown();
} private static class Task implements Runnable{
private String name; Task(String name) {
this.name = name;
} @Override
public void run() {
System.out.println(Thread.currentThread().getName() + "===" + name);
}
} }

运行:

2. DiscardPolicy(丢弃任务,但是不抛出异常)

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; public class Test { public static void main(String[] args) throws Exception {
ThreadPoolExecutor pool = new ThreadPoolExecutor(
1,
2,
0L,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(3),
// 拒绝但不抛出异常
new ThreadPoolExecutor.DiscardPolicy()); for (int i = 0; i < 6; i++){
pool.execute(new Task("任务" + i));
}
pool.shutdown();
} private static class Task implements Runnable{
private String name; Task(String name) {
this.name = name;
} @Override
public void run() {
System.out.println(Thread.currentThread().getName() + "===" + name);
}
} }

运行:

3. DiscardOldestPolicy(丢弃队列最前面的任务,然后重新提交被拒绝的任务)

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; public class Test { public static void main(String[] args) throws Exception {
ThreadPoolExecutor pool = new ThreadPoolExecutor(
1,
2,
0L,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(3),
// 丢弃队列中最前面的任务,然后执行被拒绝的任务
new ThreadPoolExecutor.DiscardOldestPolicy()); for (int i = 0; i < 6; i++){
pool.execute(new Task("任务" + i));
}
pool.shutdown();
} private static class Task implements Runnable{
private String name; Task(String name) {
this.name = name;
} @Override
public void run() {
System.out.println(Thread.currentThread().getName() + "===" + name);
}
} }

运行:

4. CallerRunsPolicy(由提交任务的线程处理)

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; public class Test { public static void main(String[] args) throws Exception {
ThreadPoolExecutor pool = new ThreadPoolExecutor(
1,
2,
0L,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(3),
// 由提交任务的线程直接执行此任务
new ThreadPoolExecutor.CallerRunsPolicy()); for (int i = 0; i < 6; i++){
pool.execute(new Task("任务" + i));
}
pool.shutdown();
} private static class Task implements Runnable{
private String name; Task(String name) {
this.name = name;
} @Override
public void run() {
System.out.println(Thread.currentThread().getName() + "===" + name);
}
} }

运行:

5. 自己处理

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; public class Test { public static void main(String[] args) throws Exception {
ThreadPoolExecutor pool = new ThreadPoolExecutor(
1,
2,
0L,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(3),
// 自定义处理
(Runnable r, ThreadPoolExecutor executor) -> {
System.out.println("自定义处理");
}); for (int i = 0; i < 6; i++){
pool.execute(new Task("任务" + i));
}
pool.shutdown();
} private static class Task implements Runnable{
private String name; Task(String name) {
this.name = name;
} @Override
public void run() {
System.out.println(Thread.currentThread().getName() + "===" + name);
}
} }

运行:

线程池之ThreadPoolExecutor的更多相关文章

  1. 从源码解读线程(Thread)和线程池(ThreadPoolExecutor)的状态

    线程是比进程更加轻量级的调度执行单位,理解线程是理解并发编程的不可或缺的一部分:而生产过程中不可能永远使用裸线程,需要线程池技术,线程池是管理和调度线程的资源池.因为前不久遇到了一个关于线程状态的问题 ...

  2. Java并发编程:Java线程池核心ThreadPoolExecutor的使用和原理分析

    目录 引出线程池 Executor框架 ThreadPoolExecutor详解 构造函数 重要的变量 线程池执行流程 任务队列workQueue 任务拒绝策略 线程池的关闭 ThreadPoolEx ...

  3. 线程池 一 ThreadPoolExecutor

    java.util.concurrent public class ThreadPoolExecutor extends AbstractExecutorService ThreadPoolExecu ...

  4. 线程池之 ThreadPoolExecutor

    线程池之 ThreadPoolExecutor + 面试题 线程池介绍 线程池(Thread Pool):把一个或多个线程通过统一的方式进行调度和重复使用的技术,避免了因为线程过多而带来使用上的开销. ...

  5. 高并发之——不得不说的线程池与ThreadPoolExecutor类浅析

    一.抛砖引玉 既然Java中支持以多线程的方式来执行相应的任务,但为什么在JDK1.5中又提供了线程池技术呢?这个问题大家自行脑补,多动脑,肯定没坏处,哈哈哈... 说起Java中的线程池技术,在很多 ...

  6. 【高并发】不得不说的线程池与ThreadPoolExecutor类浅析

    大家好,我是冰河~~ 今天,我们一起来简单聊聊线程池中的ThreadPoolExecutor类,好了,不多说了,开始进入今天的正题. 一.抛砖引玉 既然Java中支持以多线程的方式来执行相应的任务,但 ...

  7. 线程池:ThreadPoolExecutor

    [ThreadPoolExecutor的使用和思考]   public ThreadPoolExecutor(int corePoolSize,                             ...

  8. Java线程池之ThreadPoolExecutor

    前言 线程池可以提高程序的并发性能(当然是合适的情况下),因为对于没有线程的情况下,我们每一次提交任务都新建一个线程,这种方法存在不少缺陷: 1.  线程的创建和销毁的开销非常高,线程的创建需要时间, ...

  9. 从源码看JDK提供的线程池(ThreadPoolExecutor)

    一丶什么是线程池 (1)博主在听到线程池三个字的时候第一个想法就是数据库连接池,回忆一下,我们在学JavaWeb的时候怎么理解数据库连接池的,数据库创建连接和关闭连接是一个比较耗费资源的事情,对于那些 ...

  10. java并发线程池---了解ThreadPoolExecutor就够了

    总结:线程池的特点是,在线程的数量=corePoolSize后,仅任务队列满了之后,才会从任务队列中取出一个任务,然后构造一个新的线程,循环往复直到线程数量达到maximumPoolSize执行拒绝策 ...

随机推荐

  1. 分布式监控系统Zabbix-3.0.3-完整安装记录(1)

    分布式监控系统Zabbix-3.0.3的安装记录 环境说明zabbix-server:192.168.1.30     #zabbix的服务端(若要监控本机,则需要配置本机的Zabbix agent, ...

  2. Linux下Redis主从复制以及SSDB主主复制环境部署记录

    前面的文章已经介绍了redis作为缓存数据库的说明,本文主要说下redis主从复制及集群管理配置的操作记录: Redis主从复制(目前redis仅支持主从复制模式,可以支持在线备份.读写分离等功能.) ...

  3. JAVA SOCKET编程单线程简单实例

    服务端: package socketProgram; import java.io.BufferedReader;import java.io.IOException;import java.io. ...

  4. PAT 1071 小赌怡情

    https://pintia.cn/problem-sets/994805260223102976/problems/994805264312549376 常言道“小赌怡情”.这是一个很简单的小游戏: ...

  5. doc.update

    db.collection('todos').doc('todo-identifiant-aleatoire').update({ // data 传入需要局部更新的数据 data: { // 表示将 ...

  6. hive web界面管理

    老版本使用 访问<Hive Server Address>:9999/hwi 1.首先下载对应版本的src文件,本机使用apache-hive-1.2.2-src.tar.gz 2.解压缩 ...

  7. git常用命令及用法小计

    git init 初始化一个本地git仓库repository git status 查看状态 git add <file> 将工作区修改加到暂存区(stage) git commit - ...

  8. BZOJ3523[Poi2014]Bricks——贪心+堆

    题目描述 有n种颜色的砖块,第i种颜色的砖块有a[i]个,你需要把他们放成一排,使得相邻两个砖块的颜色不相同,限定第一个砖块的颜色是start,最后一个砖块的颜色是end,请构造出一种合法的方案或判断 ...

  9. 睡前小dp-poj2096-概率dp

    http://poj.org/problem?id=2096 有n种分类,s种子系统,相互独立.每天发现一个bug等概率的属于n种分类和s种子系统. 要使发现的bug完全覆盖n种分类,s种分类,求天数 ...

  10. java构造函数总结

    构造函数总结 概念:    创建对象时由JVM自动调用的函数 作用:    在创建对象的时候给对象的成员变量赋值: 写法: 修饰符:可以用访问权限修饰符(public.private等)修饰:不能用s ...