Executors和ThreadPoolExecutor详解

article/2025/9/9 2:32:55

概述

在《阿里巴巴java开发手册》中指出了线程资源必须通过线程池提供,不允许在应用中自行显示的创建线程,这样一方面是线程的创建更加规范,可以合理控制开辟线程的数量;另一方面线程的细节管理交给线程池处理,优化了资源的开销。而线程池不允许使用Executors去创建,而要通过ThreadPoolExecutor方式,这一方面是由于jdk中Executor框架虽然提供了如newFixedThreadPool()、newSingleThreadExecutor()、newCachedThreadPool()等创建线程池的方法,但都有其局限性,不够灵活;另外由于前面几种方法内部也是通过ThreadPoolExecutor方式实现,使用ThreadPoolExecutor有助于大家明确线程池的运行规则,创建符合自己的业务场景需要的线程池,避免资源耗尽的风险

1、线程池的七种创建方式

Executors 创建的六种

  1. Executors.newFixedThreadPool:创建一个固定大小的线程池,可控制并发的线程数,超出的线程会在队列中等待;
  2. Executors.newCachedThreadPool:创建一个可缓存的线程池,若线程数超过处理所需,缓存一段时间后会回收,若线程数不够,则新建线程;
  3. Executors.newSingleThreadExecutor:创建单个线程数的线程池,它可以保证先进先出的执行顺序;
  4. Executors.newScheduledThreadPool:创建一个可以执行延迟任务的线程池;
  5. Executors.newSingleThreadScheduledExecutor:创建一个单线程的可以执行延迟任务的线程池;
  6. Executors.newWorkStealingPool:创建一个抢占式执行的线程池(任务执行顺序不确定)【JDK 1.8 添加】

示例:

ExecutorService executorService = Executors.newFixedThreadPool(3);

ThreadPoolExecutor 创建的一种(ThreadPoolExecutor:最原始的创建线程池的方式,它包含了 7 个参数可供设置)

ThreadPoolExecutor提供了四个构造方法:

    public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {}public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {}public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {}public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {}

参数详解:

    public ThreadPoolExecutor(int corePoolSize, //核心线程数,线程池中始终存活的线程数int maximumPoolSize, //最大线程数,线程池中允许的最大线程数long keepAliveTime, //最大线程数可以存活的时间TimeUnit unit, //时间单位BlockingQueue<Runnable> workQueue, //阻塞队列,workQueue包含七种ThreadFactory threadFactory, //线程工厂,主要用来创建线程RejectedExecutionHandler handler //拒绝策略) {super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);this.prestartAllCoreThreads();}

实例:

    private static ExecutorService executorService;public static void main( String[] args ) {executorService = new ThreadPoolExecutor(2, 4, 1000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(5),new ThreadFactory() {public Thread newThread(Runnable runnable) {log.info("创建线程:{}",runnable.hashCode());Thread threadName = new Thread(runnable,"threadPool"+runnable.hashCode());return threadName;}}, new ThreadPoolExecutor.CallerRunsPolicy());// ThreadTask类实现Runnable接口,这里省略了executorService.execute(new ThreadTask());}

ThreadPoolExecutor执行原理概述

点击executorService.execute(new ThreadTask())的execute()方法
public void execute(Runnable command) {if (command == null)throw new NullPointerException();int c = ctl.get();// 1、工作线程 < 核心线程 if (workerCountOf(c) < corePoolSize) {if (addWorker(command, true))return;c = ctl.get();}// 2、运行态,并尝试将任务加入队列if (isRunning(c) && workQueue.offer(command)) {int recheck = ctl.get();if (! isRunning(recheck) && remove(command))reject(command);else if (workerCountOf(recheck) == 0)addWorker(null, false);} // 3、使用尝试使用最大线程运行else if (!addWorker(command, false))reject(command);}

这三处if判断,还是比较泛的,整体大框框上的流程,可用下图表示:

上述代码中的三种传参方式:

  1. addWorker(command, true): 创建核心线程执行任务;
  2. addWorker(command, false):创建非核心线程执行任务;
  3. addWorker(null, false): 创建非核心线程,当前任务为空;

     addWorker的工作可分为两个部分:

  • 第一部分:原子操作,判断是否可以创建worker。通过自旋、CAS、ctl 等操作,判断继续创建还是返回false,自旋周期一般很短。
  • 第二部分:同步创建workder,并启动线程。

    ThreadPoolExecutor的执行主要围绕Worker,Worker 实现了 AbstractQueuedSynchronizer 并继承了 Runnable

ExecutorService转换为ThreadPoolExecutor获取当前活动线程数

    public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(3);// 获取当前活动线程数int activeCount = ((ThreadPoolExecutor) executorService).getActiveCount();}

ThreadPoolExecutor常用方法:

Modifier and Type

Method and Description
protected voidafterExecute(Runnable r, Throwable t)

完成指定Runnable的执行后调用方法。

voidallowCoreThreadTimeOut(boolean value)

设置策略是否核心线程可能会超时,如果任务没有在活着的时间内到达,则在新任务到达时被替换。

booleanallowsCoreThreadTimeOut()

如果此池允许核心线程超时并终止,如果没有任务在keepAlive时间内到达,则返回true,如果新任务到达时需要更换。

booleanawaitTermination(long timeout, TimeUnit unit)

阻止所有任务在关闭请求完成后执行,或发生超时,或当前线程中断,以先到者为准。

protected voidbeforeExecute(Thread t, Runnable r)

在给定的线程中执行给定的Runnable之前调用方法。

voidexecute(Runnable command)

在将来某个时候执行给定的任务。

protected voidfinalize()

当这个执行器不再被引用并且没有线程时,调用 shutdown 。

intgetActiveCount()

返回正在执行任务的线程的大概数量。

longgetCompletedTaskCount()

返回完成执行的任务的大致总数。

intgetCorePoolSize()

返回核心线程数。

longgetKeepAliveTime(TimeUnit unit)

返回线程保持活动时间,这是超过核心池大小的线程在终止之前可能保持空闲的时间量。

intgetLargestPoolSize()

返回在池中同时进行的最大线程数。

intgetMaximumPoolSize()

返回允许的最大线程数。

intgetPoolSize()

返回池中当前的线程数。

BlockingQueue<Runnable>getQueue()

返回此执行程序使用的任务队列。

RejectedExecutionHandlergetRejectedExecutionHandler()

返回不可执行任务的当前处理程序。

longgetTaskCount()

返回计划执行的任务的大概总数。

ThreadFactorygetThreadFactory()

返回用于创建新线程的线程工厂。

booleanisShutdown()

如果此执行者已关闭,则返回 true 。

booleanisTerminated()

如果所有任务在关闭后完成,则返回 true 。

booleanisTerminating()

如果此执行者在 shutdown()或 shutdownNow()之后 终止 ,但尚未完全终止,则返回true。

intprestartAllCoreThreads()

启动所有核心线程,导致他们等待工作。

booleanprestartCoreThread()

启动核心线程,使其无法等待工作。

voidpurge()

尝试从工作队列中删除已取消的所有Future任务。

booleanremove(Runnable task)

如果此任务存在,则从执行程序的内部队列中删除此任务,从而导致该任务尚未运行。

voidsetCorePoolSize(int corePoolSize)

设置核心线程数。

voidsetKeepAliveTime(long time, TimeUnit unit)

设置线程在终止之前可能保持空闲的时间限制。

voidsetMaximumPoolSize(int maximumPoolSize)

设置允许的最大线程数。

voidsetRejectedExecutionHandler(RejectedExecutionHandler handler)

为不可执行的任务设置一个新的处理程序。

voidsetThreadFactory(ThreadFactory threadFactory)

设置用于创建新线程的线程工厂。

voidshutdown()

启动有序关闭,其中先前提交的任务将被执行,但不会接受任何新任务。

List<Runnable>shutdownNow()

尝试停止所有主动执行的任务,停止等待任务的处理,并返回正在等待执行的任务列表。

protected voidterminated()

执行程序已终止时调用方法。

StringtoString()

返回标识此池的字符串及其状态,包括运行状态和估计的工作人员和任务计数的指示。

查询文档  Java 8 中文版 - 在线API中文手册

 

 


http://chatgpt.dhexx.cn/article/hO3QgLfX.shtml

相关文章

4.Executor执行器

1.Executor 主体结构 Executor是MyBatis执行者接口&#xff0c;执行器的功能包括&#xff1a; 基本功能&#xff1a;改、查&#xff0c;没有增删的原因是&#xff0c;所有的增删操作都可以归结到改。缓存维护&#xff1a;这里的缓存主要是为一级缓存服务&#xff0c;功能包括…

ExecutorService

本文翻译自http://tutorials.jenkov.com/java-util-concurrent/executorservice.html&#xff0c;人工翻译&#xff0c;仅供学习交流。 ExecutorService java.util.concurrent.ExecutorService接口是一种能够在后台并发执行任务的异步执行机制。本文中&#xff0c;我将会介绍…

Executor概述

在Java类库中&#xff0c;任务执行的主要抽象不是Thread&#xff0c;而是Executor。 public interface Executor {void execute(Runnable command); }它为灵活且强大的异步任务执行框架提供了基础&#xff0c;该框架能支持多种不同类型的任务执行策略。它提供了一种标准的方法…

Executor框架简介

Executor系统中&#xff0c;将线程任务提交和任务执行进行了解耦的设计; 线程被一对一映射为服务所在操作系统线程&#xff0c;启动时会创建一个操作系统线程&#xff1b;当该线程终止时&#xff0c;这个操作系统线程也会被回收 Executor框架包含的核心接口和主要的实现类 具体…

Executors 源码解析(JDK8)

前言 本文隶属于专栏《100个问题搞定Java并发》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和参考文献请见100个问题搞定Java并发 正文 类注释 /*** Factory and util…

Executor框架

转载请以链接形式标明出处&#xff1a; 本文出自:103style的博客 Java并发编程的艺术笔记 并发编程的挑战Java并发机制的底层实现原理Java内存模型Java并发编程基础Java中的锁的使用和实现介绍Java并发容器和框架Java中的12个原子操作类介绍Java中的并发工具类Java中的线程池E…

Executor执行器

分为四个模块&#xff1a; 1.动态代理MapperProxy 2.SQL会话SqlSesson 3.执行器Executor 4.JDBC处理器StatementHandler 现讲述为SQL会话与执行器 一、SQL会话SqlSesson 该门面模式提供一个统一的门面接口API 该模式提供的一个基本API为增删改查&#xff0c;还会提供提…

Java并发多线程编程——Executors类

目录 一、Executors的理解二、Executors类图结构二、Executors常用的方法三、线程池的创建分为两种方式&#xff08;主要介绍通过Executors类创建的方式&#xff09;1、newFixedThreadPool方法示例2、newSingleThreadExecutor方法示例3、newCachedThreadPool方法4、newSchedule…

Executors一篇就够

Executors框架包含的内容十分的多&#xff1a;看图&#xff1a; 一、各个接口的作用 按照图示关系进行介绍&#xff1a; Executor 该接口作为顶层接口只有一个execute()方法 execute(Runnable r) 该接口接受一个Runnable实例&#xff0c;即要执行的任务ExecutorService 该…

Executors工具类的相关方法

前言&#xff1a;大家好&#xff0c;我是小威&#xff0c;24届毕业生。本篇将记录创建线程池的Executors工具类里面的方法&#xff0c;方便加深知识印象和复习使用。 本篇文章记录的基础知识&#xff0c;适合在学Java的小白&#xff0c;也适合复习中&#xff0c;面试中的大佬&a…

java并发编程:Executor、Executors、ExecutorService

Executors 在Java 5之后&#xff0c;并发编程引入了一堆新的启动、调度和管理线程的API。Executor框架便是Java 5中引入的&#xff0c;其内部使用了线程池机制&#xff0c;它在java.util.cocurrent 包下&#xff0c;通过该框架来控制线程的启动、执行和关闭&#xff0c;可以简化…

nlinfit非线性回归拟合

% % 使用指定函数对下述两变量进行曲线拟合 % % yak1*exp(m*t)k2*exp(-m*t); % % 离散点: t[0,4,8,40], % % y[20.09,64.52,85.83,126.75]; % % t-自变量 y-因变量 a,m,k1,k2为常数 % % 用非线性回归nlinfit&#xff0c;如果数据点多些&#xff0c;效果会更好。 脚本&…

matlab的nlinfit函数,用matlab如何进行非线性拟合 nlinfit函数?

用非线性回归nlinfit&#xff0c;如果数据点多些&#xff0c;效果会更好。 function nonlinefit clc;clear; t[0 4 8 40]; y[20.09 64.52 85.83 126.75]; betanlinfit(t,y,myfunc,[1 1 1 1]) abeta(1) k1beta(2) k2beta(3) mbeta(4) tt0:1:40 yyak1*exp(m*tt)k2*exp(-m*tt) plo…

【MATLAB统计分析与应用100例】案例013:matlab读取Excel数据,调用nlinfit函数作一元非线性回归

1. 一元线性回归分析效果预览 2. matlab完整实现代码 %读取数据,绘制散点图** HeadData = xlsread(examp08_02.xls); %从Excel文

matlab中用polyfit、regress、nlinfit等进行详细的回归分析

目录 1.说明2.回归的介绍2-1.前面两篇所发现的一些问题2-1-1.回归和拟合是什么关系?2-1-2.回归到底是做预测还是用来去脏数据?3.三个函数的核心:最小二乘法3-1.介绍3-2.matlab代码4.函数polyfit(线性)5.函数regress(线性)5-1.输出b,bint,r,rint,stats5-2.应用5.2-1.一元…

曲线拟和函数lsqcurvefit nlinfit

转载自&#xff1a;http://panda0411.com/2011/08/29/curve-fit-and-function-lsqcurvefitnlinfit/ 琢磨了好久matlab自带的曲线拟和工具箱, 发现这货只能解决从离散数据得到各种类型的拟和效果, 但是反之貌似没法实现, google一下有这两个函数可以用:lsqcurvefit和nlinfit ls…

Matlab学习手记——非线性数据拟合:nlinfit和lsqcurvefit

目的&#xff1a;通过一个实例了解Matlab的数据拟合函数nlinfit和lsqcurvefit的使用。 结果图 具体数值 p 0.3000 50.0000 0.4000 200.0000 0.3000 800.0000 p1 0.3267 48.3589 0.4030 226.6525 0.2838 809.6680 p2 0.3267 48.3646 0.4031 226.735…

MATLAB多元非线性回归nlinfit拟合圆拟合球拟合函数

先上实验效果&#xff0c;你觉得有帮助可以继续阅读。代码解析在B站有上传视频&#xff08;用户昵称同名&#xff09;&#xff0c;代码也有详细备注。 拟合圆和球面&#xff1a; 拟合多元非线性函数&#xff1a;y p1*x1p2*x1^2p3*x2p4*x2^2exp(-p5*x3)的拟合结果&#xff1a;…

MATLAB 非线性隐函数拟合采坑记录(使用 fsolve solve nlinfit lsqcurvefit函数)

MATLAB 非线性隐函数拟合采坑记录&#xff08;使用 fsolve solve nlinfit lsqcurvefit函数&#xff09; 问题描述解决思路错误示范1代码思路原因解释模型更正更正模型1更正模型2 错误示范2代码思路原因解释模型更正更正模型1更正模型2 总结 问题描述 MATLAB的 nlinfit 和 lsqc…

Matlab多元非线性函数拟合

看了多篇文章&#xff0c;觉得没有一篇比较全&#xff0c;且可以参照的多元非线性函数拟合&#xff0c;看了多篇文章后总结以下内容&#xff0c;主要以示例给出&#xff0c;希望能帮助到大家快速上手。 1.需要用到的函数语法 beta nlinfit(X, Y, modelfun, beta0) X为你的自…