Java线程池-ThreadPoolExecutor,Executors使用示例

Executors与ThreadPoolExecutor(阿里发布的 Java开发手册中强制线程池不允许使用 Executors 去创建) 最近阿里发布的 Java开发手册中强制线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险 Executors利用工厂模式向我们提供了4种线程池实现方式,但是并不推荐使用,原因是使用Executors创建线程池不会传入这个参数而使用默认值所以我们常常忽略这一参数,而且默认使用的参 阅读详情

1. Executors简单示例

java提供了Executors线程池创建工具方便我们创建合适的线程池,示例如下,提供了四种创建线程池的简单方法,当然,其中有各自的优劣,之后 再叙述。

//创建一个会根据需要自动创建线程的线程池,并且有空闲线程存在时,不再创建新的线程,将重用该空闲线城池
ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); 
//创建并保持固定数量的线程池
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
//利用主机上可用处理器的数量作为目标并行级别,创建一个基于工作-窃取算法的线程池
ExecutorService workStealingPool = Executors.newWorkStealingPool();
//创建一个线程池,可以调度命令在指定延迟后运行或周期性执行
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(10);

接下来,根据上面java提供的简单方法创建一个CachedThreadPool简单的示例。

public class CachedTheadPoolDemo {

    public static void main(String[] args){
        // 创建线程池
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        // 创建3个线程
        for (int i = 0; i < 3; i++) {
            CustomTask customTask = new CustomTask(i + "");
            cachedThreadPool.execute(customTask);
        }
    }
}

// 自定义一个任务
class CustomTask extends Thread {

    private String taskName;

    public CustomTask(String taskName){
        this.taskName = taskName;
    }
    @Override
    public void run() {
        // 循环打印出任务名和标签
        for (int i = 0; i < 3; i++) {
            System.out.println("Task: "+taskName+", Tag: "+i);
        }
    }
}

运行结果如下,

Task: 0, Tag: 0
Task: 1, Tag: 0
Task: 2, Tag: 0
Task: 1, Tag: 1
Task: 0, Tag: 1
Task: 1, Tag: 2
Task: 2, Tag: 1
Task: 0, Tag: 2
Task: 2, Tag: 2

2. ThreadPoolExecutor简单示例

在阿里巴巴java开发规范手册中,并不推荐使用Executors工具去创建线程池,而是使用ThreadPoolExecutor创建线程池,至于原因,在下面再讨论。那么,先看看ThreadPoolExecutor是怎么创建线程池的,示例如下

import java.util.concurrent.*;

public class ThreadPoolExecutorDemo {

    public static void main(String[] args){

        int corePoolSize = 4;  // 一直保持在线程池内的线程数量,这个数量内的线程就算空闲也不会被回收,除非设置了allowCoreThreadTimeOut
        int maximumPoolSize = 8; // 线程池允许持有的最大线程数量
        long keepAliveTime = 10; // 当线程数量大于核心线程数量(corePoolSize)时,回收空闲线程的最大时间
        TimeUnit unit = TimeUnit.SECONDS; // keepAliveTime的时间单位
        BlockingQueue<Runnable> workQueue = new LinkedBlockingDeque<>(4); // 保存被执行前任务的队列,这个队列只会保存被execute方法提交的Runnable任务
        ThreadFactory threadFactory = Executors.defaultThreadFactory(); // 创建线程的工厂类
        RejectedExecutionHandler rejectedPolicy = new ThreadPoolExecutor.AbortPolicy(); // 当线程阻塞并且达到任务队列最大容量时调用的处理器

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, rejectedPolicy);
        for (int i = 0; i < 3; i++) {
            CustomTask customTask = new CustomTask(i + "");
            threadPoolExecutor.execute(customTask);
        }

    }
}

class CustomTask extends Thread {

    private String taskName;

    public CustomTask(String taskName){
        this.taskName = taskName;
    }
    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            System.out.println("Task: "+taskName+", Tag: "+i);
        }
    }
}

控制台输出结果,

Task: 2, Tag: 0
Task: 1, Tag: 0
Task: 0, Tag: 0
Task: 1, Tag: 1
Task: 2, Tag: 1
Task: 1, Tag: 2
Task: 0, Tag: 1
Task: 2, Tag: 2
Task: 0, Tag: 2

 

3. Executors源码分析

在第1节中,以及了解到了Executors线程池创建工具的简单使用,那么这一节将从源码的角度去看待各种创建方法的不同。

3.1 CachedThreadPool

// 创建一个可以根据需要创建新线程的线程池
public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                   new SynchronousQueue<Runnable>());
}

定义:Executors调用newCachedThreadPool()方法创建一个线程池,该线程池的核心线程数为0,线程池可持有的最大线程数为Integer类型的最大值2^{31}-1,回收空闲线程的等待时间为60秒,采用阻塞队列保存任务(Task)。

 

3.2 FixedThreadPool

// 创建一个保存固定线程数量的线程池
public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

定义:Executors调用newFixedThreadPool(int nThreads)方法创建一个核心线程数量和线程数量相同的线程池,采用基于linked nodes的可选非阻塞队列保存任务,队列初始容量为Integer类型的最大值2^{31}-1。

3.3 WorkStealingThreadPool

//用可用处理器数量作为目标并行级别创建一个work-stealing的线程池
public static ExecutorService newWorkStealingPool() {
    return new ForkJoinPool
         (Runtime.getRuntime().availableProcessors(),
          ForkJoinPool.defaultForkJoinWorkerThreadFactory,
          null, true);
}

定义: Executors调用newWorkStealingPool()方法创建一个线程池,该线程池为ForkJoinPool线程池,继承了AbstractExecutorService,使用DefaultForkJoinWorkerThreadFactory作为默认创建新线程的工厂类,默认对内部工作线程执行任务出现不可恢复错误时不做任何处理,并为未加入的forked task建立本地先进先出的任务调度模式。

3.4 ScheduledThreadPool

// Executors中,传入核心线程数调用ScheduledThreadPool的构造函数,创建线程池
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
   return new ScheduledThreadPoolExecutor(corePoolSize);
}




// ScheduledThreadPoolExecutor中构造函数,创建一个线程池
public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE,
              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
              new DelayedWorkQueue());
    }

定义: Executors调用newScheduledThreadPool方法时,会间接调用ScheduledThreadPoolExecutor的构造函数创建线程池,该线程池核心线程数为corePoolSize,可持有的最大线程数为Integer类型的最大值2^{31}-1,回收空闲线程的默认时间为10毫秒,采用一个专门的延迟队列,该队列也为阻塞队列,初始容量为16。

路径规划:D*Lite寻路算法详解 D*Lite详解目录 阅读详情

相关推荐

inferCNVpy分析流程学习

inferCNV的用途大家都已经很清楚了,接下来就走一下流程,试一试Python版的inferCNV。使用的数据集为:GSE188711,既往推文可见:Scanpy分析全流程(含harmonypy整合/细胞周期矫正/双细胞检测及去除)(

zfyyzhys的博客 1295

Java中的线程池——ThreadPoolExecutor的使用

开发过程中,合理地使用线程池可以带来3个好处: 降低资源消耗:通过重复利用已创建的线程降低线程创建和销毁造成的消耗。 提高响应速度:当任务到达时,任务可以不需要等到线程创建就能立即执行。 提高线程的可管理性:线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配、调优和监控。 1 线程池的创建 ThreadPoolExecutor有

惟愿无事 4万+

Error relaunching VirtualBox VM process:5错误解决

前几天在重新使用VirtualBox的时候出现了一个挺恶心的错误,如图 百度了好久没有找到合适的解决方法。功夫不负有心人,在查阅了vb相关论坛时发现了大牛对此问题的诸多解决方案。下面我把此论坛的内容总结一下,希望对大家有帮助。 论坛链接:Diagnosing VirtualBox Hardening Issues 时间不足的小伙伴可以直接看 解决方法 造成这个错误的主要原因是,windows操作系统与oracle vb的不兼容。有两个方面,一是非官方windows系统中包含了一些没有签名的d

JaCenz的博客 3万+

深入学习java源码之Executors.newFixedThreadPool()与Executors.newCachedThreadPool()

深入学习java源码之Executors.newFixedThreadPool()与Executors.newCachedThreadPool() Executor框架是指java5中引入的一系列并发库中与executor相关的一些功能类,其中包括线程池,Executor,Executors,ExecutorService,CompletionService,Future,Callable等。他...

悦分享 3万+

告别卡顿!OBS Studio最佳录制参数设置指南(适合游戏/网课/会议场景)

本文提供OBS Studio录制参数优化指南,针对游戏、网课及会议三大场景,详细解析帧率、码率与编码器设置。重点推荐利用硬件编码器(如NVENC)实现游戏录制零卡顿,并分享清晰稳定的网课录制与长时间会议录制配置方案,助你告别视频卡顿与音画不同步问题。

e4f5g6h7的博客 1330

VisionMaster Qt二次开发:图像获取、COM组件渲染与本地化存储实战

本文详细介绍了基于VisionMaster进行Qt二次开发的核心实战流程,涵盖环境搭建、方案加载、图像数据获取、COM组件渲染与本地化存储。重点解析了如何通过COM组件在Qt界面中实时显示图像,以及将VM图像数据转换为QImage并保存为本地文件的关键步骤与常见问题,为工业视觉项目开发提供稳定高效的解决方案。

weixin_29229261的博客 205

线程池ThreadPoolExecutor的例子,Executors.newFixedThreadPool实现

通过源码可以看到,本质上,Executors.newSingleThreadExecutor();或者Executors.newFixedThreadPool(args);等等,都是在new ThreadPoolExecutor();只是给ThreadPoolExecutor传递参数不通罢了。 最近项目中有这样一个功能:需要短时间内调用外部接口发送大量短信。于是想到了线程池。发送短信有多个账号,

li118100的专栏 3057

【AI落地】AI生成测试用例,claude or gpt?(提效至少 50%)

gpt生成测试用例?当然好使啦,用好了提效50%+,用不好就让他变好!

青禾tester 1967

Executors多线程编程实例之newFixedThreadPool

基础储备: java.util.concurrent 类 Executors java.lang.Object 继承者 java.util.concurrent.Executors 此类是个工具类,它提供对Executor、ExecutorService、ScheduledExecutorService、ThreadFactory 和 Callable 类的一些实用方法。 此类支持

一轮明月半城沙 1167

42、多媒体与虚拟现实在艺术和影视领域的创新应用

本文探讨了多媒体与虚拟现实在艺术和影视领域的创新应用,涵盖三个典型案例:影视与人类学融合项目通过协作模式模糊作者与观众界限,推动文化文献的发展;交互式数字短片《分手》利用基于对象的广播技术探索个性化影视体验;威尼斯双年展瑞士馆4D项目则通过虚拟现实技术实现文化遗产的数字化展示。这些案例展示了技术在叙事、用户体验及文化保护中的深度应用,并展望了未来技术融合、个性化深化与文化遗产传承的发展趋势。

kappa的博客 114

mybaits-plus通用CRUD详解及代码案例

文章目录mybaitsplus通用CRUD插入操作方法定义测试用例mybaitsplus主键生成策略设置自增主键设置输入主键:UUID:ID_WORKER_STR:ID_WORKER:更新操作根据id更新方法定义:方法步骤根据条件更新方法定义:更新步骤:根据条件更新(可以更新NULL)删除操作根据id删除方法定义:删除步骤:根据 entity 条件删除方法定义:删除步骤:根据ID 批量删除方法定义:删除步骤:查询操作根据id查询方法定义:查询步骤:根据id批量查询方法定义:查询步骤:根据 entity 条件

流楚丶格念的博客 3405

【Java进阶】线程池之无限队列 - 使用工厂类Executors.newFixedThreadPool(n) ,创建无限队列线程池

线程池底层实现 线程池的底层实现是:ThreadPoolExecutor 使用工厂类Executors快速创建预定义线程池 IDEA插件Alibaba Java Coding Guidelines,代码提示如下(马云不推荐使用啊) 线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。 说明:Executors 返回的线程池对象的弊端如下: 1) FixedThreadPool 和

卡萨的博客 2682

《QGIS快速入门与应用基础》009:国内镜像源(清华大学/阿里云)下载技巧

针对国内用户下载QGIS速度慢、易中断的问题,推荐使用清华大学和阿里云两大国内镜像源,提供3-10MB/s的极速下载方案。详细解析镜像源核心优势、分步骤下载指南及校验方法,对比清华(同步快、北方优选)与阿里云(南方节点多)的特点。针对常见问题如版本延迟、404错误等提供解决方案,并介绍搭配IDM等工具实现多线程加速的进阶技巧。通过镜像源+下载工具组合,用户可高效获取QGIS安装包,为后续系统安装奠定基础。

LuckyHanMo的博客 1732

Java —— Executors、ExecutorService、ThreadPoolExecutor线程池

Executors类 工具类、线程池的工厂类,用于创建并返回不同类型的线程池。 Executors.newCachedThreadPool():创建一个可根据需要创建新线程的线程池 Executors.newFixedThreadPool(n); 创建一个可重用固定线程数的线程池 Executors.newSingleThreadExecutor() :创建一个只有一个线程的线程池 Ex...

Hern(宋兆恒) 689

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Java线程池详解:ExecutorService、ThreadPoolExecutor、Executors

线程池就是一个可以复用线程的技术。多线程不使用线程池带来的问题 如果用户每发起一个请求,后台就创建一个新线程来处理,下次新任务来了又要创建新线程,而创建新线程的开销是很大的,这样会严重影响系统的性能。线程池的工作原理谁代表线程池 JDK 5.0起提供了代表线程池的接口:ExecutorService。方式一:使用ExecutorService的实现类ThreadPoolExecutor自创建一个线程池对象; 方式二:使用Executors(线程池......

斯文~ 1823

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Java线程池 ExecutorService、ThreadPoolExecutor、ScheduledThreadPoolExecutor及Executors工厂类

Java中的线程池类有两个,分别是:ThreadPoolExecutor和ScheduledThreadPoolExecutor,这两个类都继承自ExecutorService。利用这两个类,可以创建各种不同的Java线程池,为了方便我们创建线程池,Java API提供了Executors工厂类来帮助我们创建各种各样的线程池。下面我们分别介绍一下这三个类。 Java线程池ExecutorService继承树: 1、ExecutorService介绍 ExecutorService是Java中对线.

Janson_Lin 2404

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

【Java多线程】线程池 ThreadPoolExecutor类和Executors工厂类以及线程池的最优大小

主要核心原理 创建一个线程池子,池子中是空的 提交任务时,线程池子会创建新的线程对象,任务执行完毕,线程归还给池子下回再次提交任务时,不需要创建新的线程,直接复用已有的线程即可 但是如果提交任务时,池子中没有空闲线程,也无法创建新的线程,任务就会排队等待

m0_65277261的博客 2257

Java线程池类ThreadPoolExecutor、ScheduledThreadPoolExecutor及Executors工厂类

Java中的线程池类有两个,分别是:ThreadPoolExecutor和ScheduledThreadPoolExecutor,这两个类都继承自ExecutorService。利用这两个类,可以创建各种不同的Java线程池,为了方便我们创建线程池,Java API提供了Executors工厂类来帮助我们创建各种各样的线程池。下面我们分别介绍一下这三个类。Java线程池ExecutorService

Heaven Wang 的专栏 1万+

java线程池总结(ThreadPoolExecutor与Executors特性及使用)

1. 线程池简介 线程池是指预先创建好一定数量的线程对象,存入缓冲池中,需要用的时候直接从缓冲池中取出,线程结束之后会再回到缓冲池中 线程池在java中用ThreadPoolExecutor实现 线程池的优点 ① 提高线程的利用率 ② 提高响应速度 ③ 便于统一管理线程对象 ④ 可以控制最大的并发数 2. 线程池的使用 (1) 使用原生的ThreadPoolExecutor (2) 使用Executors 工具类 Executor接口的3种实现 ① newSingleThreadExecutor(); /

qq_43564410的博客 819

Java多线程:线程池ThreadPoolExecutor和Executors详解(六)

线程池的创建有两种:ThreadPoolExecutor 和 Executors。 线程池不是一个提高系统的并发能力的策略,是一个更好的管理线程的方案。 另外,线程池也提供了许多可调参数和可扩展性接口,以满足不同情境的需要,可以使用更方便的Executors的工厂方法,比如newCachedThreadPool (缓冲线程池,线程池线程个数最多可达Integer.MAX_ VALUE,线程自动回收)、newFixedThreadPool (固定大小的线程池)、newSingleThreadExecutor

weixin_46204877的博客 2289

Java线程池创建方式完全指南:从Executors到ThreadPoolExecutor的全面剖析

本文将系统讲解Java中创建线程池的多种方式,从Executors工具类提供的5种便捷工厂方法,到生产环境必备的ThreadPoolExecutor手动创建,以及JDK 21引入的虚拟线程池,用流程图和代码示例帮你掌握各种创建方式的适用场景与风险。核心线程数=最大线程数=1,使用无界LinkedBlockingQueue。:创建一个固定大小的线程池,核心线程数=最大线程数,使用。包提供的线程池工厂类,提供了5种创建线程池的便捷方法。,是轻量级线程的Java实现,适合。:核心线程数为0,最大线程数为。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 369

【Java 并发编程】Java 创建线程池的正确姿势: Executors 和 ThreadPoolExecutor 详解...

这种情况下,一旦提交的线程数超过当前可用线程数时,就会抛出java.util.concurrent.RejectedExecutionException,这是因为当前线程池使用的队列是有边界队列,队列已经满了便无法继续处理新的请求。其实,在上面的报错信息中,我们是可以看出蛛丝马迹的,在以上的代码中其实已经说了,真正的导致OOM的其实是LinkedBlockingQueue.offer方法。Executors的创建线程池的方法,创建出来的线程池都实现了ExecutorService接口。

AI天才研究院 1万+

java线程池案例_使用Executors 和 ThreadPoolExecutor实现Java线程池案例

并发主题使用Executors 和 ThreadPoolExecutor实现Java线程池案例首先需要一个工作线程:package com.journaldev.threadpool;public class WorkerThread implements Runnable {private String command;public WorkerThread(String s){this.c...

weixin_30929623的博客 211

Java 多线程池ThreadPoolExecutor解析及Executors类中提供的静态方法来创建线程池

使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。 一.Java中的ThreadPoolExecutor类 四个构造方法: public class ThreadPoolExecutor exten

qq_24892029的博客 2369

java多线程处理之线程池的使用(Executors、ThreadPoolExecutor)

java多线程处理之线程池的使用(Executors、ThreadPoolExecutor)前言直接上代码 前言 前几天闲的没事出去面试了一个岗位,发现了自己的不足,毕竟是c#转的java,理论知识严重不足,需要系统的学习一下,一个高并发多线程就把我震住了,并不是没用过,而是从来没有系统的整理过,唉。。。。 直接上代码 Executors import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;

qq_30225481的博客 444
上一篇: Java的volatile关键字及其示例
下一篇: 使用 vue3-tel-input电话组件时,为什么通过v-model绑定的默认值无效而 通过:value绑定有效?
小鸡炖蘑菇Plus版
博客等级 码龄10年 10粉丝 27原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值