使用 ThreadPoolExecutor 管理线程池

线程池的使用ThreadPoolExecutor 线程池意味着可以储存线程,并让池内的线程得以复用,如果池内的某一个线程执行完了,并不会直接销毁它有生命周期,可以存活一些时间,待到下一个任务来时,它会复用这个在等待中的线程,避免了再去创建线程增加的额外系统开销。CachedThreadPool∶:允许的创建线程数量为Integer .NAX_VALE,可能会创建大量的线程,我们知道每个线程默认情况下占1M的内存空间,如果线程非常多,内存资源将会被耗尽,从而导致OOM。创建线程和销毁线程的花销是比较大的,这些时间有可能比处理业务的时间还要长。 阅读详情

使用 ThreadPoolExecutor 管理线程池

在多线程编程中,线程池是一个关键的工具,可以有效地管理线程的生命周期,提高程序的性能和资源利用率。Java提供了一个强大的线程池实现,称为 ThreadPoolExecutor。

1. 引入ThreadPoolExecutor

ExecutorService executor = new ThreadPoolExecutor(
    corePoolSize,          // 核心线程数
    maximumPoolSize,       // 最大线程数
    keepAliveTime,         // 线程空闲时间
    timeUnit,              // 时间单位
    workQueue,             // 工作队列
    threadFactory,         // 线程工厂
    rejectionPolicy        // 拒绝策略
);

2. 参数解释

a. corePoolSize (核心线程数)

  • 核心线程数定义了线程池中保持活动状态的最少线程数量。
  • 当提交一个任务时,线程池会创建一个线程来处理任务,即使此时线程池中已经存在空闲的线程。
  • 如果线程池中的线程数小于 corePoolSize,即使其他线程都是空闲的,ThreadPoolExecutor 也会优先创建新的线程来处理任务。

b. maximumPoolSize (最大线程数)

  • 最大线程数定义了线程池中允许的最大线程数量。
  • 如果工作队列已满且活动线程数小于 maximumPoolSize,线程池会创建新线程来处理任务。

c. keepAliveTime (线程空闲时间)

  • 当线程数超过 corePoolSize,空闲线程的最大存活时间。
  • 超过这个时间,空闲线程会被终止,直到线程数量回到 corePoolSize。

d. timeUnit (时间单位)

  • 用于指定 keepAliveTime 的单位,可以是秒、毫秒等。

e. workQueue (工作队列)

  • 任务的排队队列,用于暂时存放等待执行的任务。
  • 可以是 LinkedBlockingQueue(无界队列)或 ArrayBlockingQueue(有界队列)等。
  • 以下是一些常用的工作队列:
  1. LinkedBlockingQueue(链表阻塞队列):

    • LinkedBlockingQueue 是一个基于链表实现的无界队列,可以无限制地增加元素。
    • 它的容量理论上可以是无限大的,适用于任务量比较大的场景。
    BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
    
  2. ArrayBlockingQueue(数组阻塞队列):

    • ArrayBlockingQueue 是一个基于数组实现的有界队列,必须指定队列的容量。
    • 当队列已满时,会拒绝新的任务。
    BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(capacity);
    
  3. SynchronousQueue(同步队列):

    • SynchronousQueue 是一个没有存储元素的队列,每个插入操作必须等待另一个线程的对应移除操作。
    • 适用于直接将任务交给线程执行,而不需要缓冲任务的场景。
    BlockingQueue<Runnable> workQueue = new SynchronousQueue<>();
    
  4. PriorityBlockingQueue(优先级队列):

    • PriorityBlockingQueue 是一个无界的优先级队列,可以根据元素的优先级顺序进行处理。
    • 需要任务实现 Comparable 接口或者传入自定义的 Comparator。
    BlockingQueue<Runnable> workQueue = new PriorityBlockingQueue<>();
    
  5. DelayQueue(延迟队列):

    • DelayQueue 是一个无界的队列,用于存放实现了 Delayed 接口的元素。
    • 元素只有在其指定的延迟时间到了才能从队列中取出。
    BlockingQueue<Runnable> workQueue = new DelayQueue<>();
    
  6. LinkedTransferQueue(链表传输队列):

    • LinkedTransferQueue 是一个无界队列,可以在生产者和消费者之间传输元素。
    • 可以通过 tryTransfer 方法尝试直接将元素传输给消费者,如果不成功则添加到队列中。
    BlockingQueue<Runnable> workQueue = new LinkedTransferQueue<>();
    
  7. LinkedBlockingDeque(链表双向阻塞队列):

    • LinkedBlockingDeque 是一个基于链表实现的无界双向队列,可以在队头和队尾插入、移除元素。
    BlockingQueue<Runnable> workQueue = new LinkedBlockingDeque<>();
    
  8. 自定义工作队列:

    • 你也可以实现自己的工作队列,只需要实现 BlockingQueue<Runnable> 接口。

总的来说,选择工作队列的类型取决于你的具体需求和场景。不同的队列类型在不同的场景下有着不同的优劣势,需要根据实际情况来选择。

f. threadFactory (线程工厂)

  • 用于创建新线程的工厂,可以自定义线程的名字、优先级等。

g. rejectionPolicy (拒绝策略)

  • 当工作队列和线程池都满了,如何处理新提交的任务。有几种策略可选:
    • ThreadPoolExecutor.AbortPolicy:直接抛出异常。
    • ThreadPoolExecutor.CallerRunsPolicy:由调用者所在的线程执行任务。
    • ThreadPoolExecutor.DiscardPolicy:直接丢弃任务。
    • ThreadPoolExecutor.DiscardOldestPolicy:丢弃最老的任务。

3. 使用示例

import java.util.concurrent.*;

public class ThreadPoolExample {
    public static void main(String[] args) {
        int corePoolSize = 5;
        int maximumPoolSize = 10;
        long keepAliveTime = 60L;
        TimeUnit timeUnit = TimeUnit.SECONDS;
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(100);
        ThreadFactory threadFactory = Executors.defaultThreadFactory();
        RejectedExecutionHandler rejectionPolicy = new ThreadPoolExecutor.CallerRunsPolicy();

        ExecutorService executor = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                timeUnit,
                workQueue,
                threadFactory,
                rejectionPolicy
        );

        // 提交任务给线程池
        for (int i = 0; i < 20; i++) {
            executor.execute(new Task(i));
        }

        // 关闭线程池
        executor.shutdown();
    }

    static class Task implements Runnable {
        private final int taskId;

        public Task(int taskId) {
            this.taskId = taskId;
        }

        @Override
        public void run() {
            System.out.println("Task " + taskId + " is running.");
        }
    }
}

在这个示例中,我们创建了一个 ThreadPoolExecutor,配置了各种参数,然后提交了20个任务给线程池执行。

protected ExecutorService executorService= new ThreadPoolExecutor(
            10,
            15,
            30,
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(1024),
            r -> {
                Thread t = new Thread(r);
                t.setName("SAVE_D_STORAGE");
                t.setPriority(Thread.NORM_PRIORITY + 2); // 增加优先级
                return t;
            },
            new ThreadPoolExecutor.CallerRunsPolicy());

4. 应用场景

ThreadPoolExecutor 适用于需要在后台执行异步任务的场景,比如:

  • Web 服务器处理请求时,可以使用线程池来处理每个请求,提高并发处理能力。
  • 后台任务的批量处理,比如数据同步、清理等。
  • 提升程序性能,避免频繁创建和销毁线程的开销。

结语

ThreadPoolExecutor 是 Java 多线程编程中非常重要的工具,能够高效地管理线程的生命周期,提高程序性能和资源利用率。合理配置线程池参数,选择适当的拒绝策略,是保证系统稳定性和性能的关键。

Python线程池模块ThreadPoolExecutor用法分析 这篇文章主要介绍了Python线程池模块ThreadPoolExecutor用法,结合实例形式分析了Python线程池模块ThreadPoolExecutor的导入与基本使用方法,需要的朋友可以参考下 文实例讲述了Python线程池模块ThreadPoolExecutor用法。分享给大家供大家参考,具体如下: python3内置的有Threadingpool和ThreadPoolExecutor模... 阅读详情

相关推荐

5分钟搞定:用Pyannote和Whisper实现带说话人分离的语音转文字(附完整代码)

本文详细介绍了如何快速构建一个集成了说话人分离功能的语音转文字系统。通过结合OpenAI的Whisper模型进行高精度语音识别和Pyannote模型实现说话人分离,并提供了完整的代码实现、环境搭建指南以及核心的对齐与合并逻辑,帮助开发者高效处理会议录音、访谈等多说话人音频,实现自动化转录。

threejs5artist的博客 635

线程池是如何管理线程的

线程池是一种用于管理和复用线程的机制,它提供了一组预先创建的线程,可以用来执行提交的任务。线程池的主要目标是提高线程的利用率和性能,并控制并发线程的数量。通过使用线程池,可以避免频繁地创建和销毁线程,减少了系统资源的消耗,并提高了线程的复用率和执行效率。

qq_46130027的博客 853

Ansys Lumerical 启动时出现 Error: Could not connect to Ansys license server specified at 1055@ 的一种解决办法

考虑到 2020 版的时候是直接在全局变量里指定具体地址,但是 2024 版本是写成 1055@localhost ,并且之后在站里搜相关 Ansys 的问题都指向 1055 端口被占用,虽然问题不一样,但是本着死马当活马医,就按照。我最近在跑超透镜结构,听说2024版本现在有GPU加速可以用,就把Lumerical从2020升到2024版本,结果发现一开头的破解办法完全不一样了。一开始安装的时候以为2020没有删干净,导致2024版的安装一直锁着目标地址,解决办法参考。的办法来操作,在关闭了。

qq_51404184的博客 5755

管理java线程池的类_Java线程池 ThreadPoolExecutor类

什么是线程池?java线程池是将大量的线程集中管理的类, 包括对线程的创建, 资源的管理, 线程生命周期的管理。当系统中存在大量的异步任务的时候就考虑使用java线程池管理所有的线程, 从而减少系统资源的开销。阿里的开发手册规范线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样 的处理方式让写的人更加明确线程池的运行规则,规避资源耗尽的风险。...

weixin_30543595的博客 295

基于JavaEE的银行大客户关系维护系统(JSP+java+springmvc+mysql+MyBatis)

基于JavaEE技术的大型银行客户关系管理系统可以实现客户信息的集中管理、客户需求的分析与挖掘、个性化的服务推荐等功能。+ Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。用户发送请求:用户通过浏览器或其他客户端向系统发送请求,请求访问特定的页面或执行特定的操作。前端展示结果:前端接收到后端返回的数据,根据需要进行展示。数据返回给前端:后端程序处理完业务逻辑后,将结果数据返回给前端。后端程序接收到请求后,根据请求的类型和参数进行相应的处理。

gp1052的博客 719

Innovus实战:5分钟搞定postRoute阶段冗余hold buffer的自动清理(附PHC识别技巧)

本文分享了在数字IC后端设计中使用Innovus工具,于postRoute阶段自动清理冗余hold buffer的实战技巧。通过配置时序感知的面积回收模式,可在5分钟内安全移除非关键路径上的PHC缓冲器,有效优化芯片面积与功耗,并附有PHC识别与验证方法。

moon9的博客 400

线程池:优化多线程管理的利器

线程池是优化并发执行的关键工具,通过合理配置参数、选择适当的任务队列和饱和策略,可以充分发挥其优势。在实际应用中,根据任务类型、负载和性能需求进行调整,动态监控线程池的状态,将使得线程池更好地适应不同的应用场景,提高系统的并发性能。

YXXXYX的博客 1452

FreeRTOS系统CPU使用率统计

操作系统中CPU使用率是在软件架构设计中必须要考虑的一个重要性能指标。它直接影响到程序的执行时间以及优先级更高的任务能否实时响应的问题。而CPU使用率也不能过低,避免资源浪费。

灵哎惹,凌沃敏的博客 1381

java线程池管理工具类

1,这是线程池管理工具类,在系统关闭时确保任务执行完毕,自定义抛弃策略默认使用了CallerRunsPolicy拒绝策略。

彦楠的博客 688

鸿蒙录屏推流应用完整解决方案

本文介绍了鸿蒙录屏推流应用的完整解决方案。项目采用分层架构设计,包含录屏、编码、推流等功能模块,要求实现4小时稳定运行且延迟小于3秒。技术实现包括:1) 通过config.json配置应用权限和功能;2) 使用ScreenRecorderManager类管理录屏服务,实现视频采集、音频录制和编码参数配置;3) 核心功能包含初始化录屏器、开始/停止录屏等操作。该方案充分利用鸿蒙系统的多媒体API,实现了高性能的屏幕录制与实时推流功能。

huanghm88的专栏 291

SAP 经营范围(Operating Concern) 和业务范围 (Business Area) 在核算架构或是管理架构中的区别和联系分别是什么 请给具体的示例

摘要:SAP系统中,业务范围(Business Area)和经营范围(Operating Concern)在核算架构中具有不同功能。业务范围是FI/CO共用维度,用于跨公司码的业务线核算(如电子产品、机械设备),支持内部管理和简单对外报表。经营范围则是CO-PA专属维度,聚焦获利能力分析,可细化到产品+客户+区域组合(如分析手机在华东区域的获利情况)。两者存在层级关联:经营范围包含业务范围作为基础维度,业务范围数据会传递至经营范围进行深度分析。实际应用中需先配置业务范围,再设置经营范围并关联相关维度,共同支

金牌架构师 96

线程池管理类和线程池类

一.线程池管理类 /** * 线程池管理类 */ public class ThreadPoolFactory { private static final Log logger = LogFactory.getLog(ThreadPoolFactory.class); /** * 放入管理线程池线程间隔时间 */ private final static int PUT_DEFAULTPOOL_INTERVAL = 3;

t194978的博客 710

Python爬虫实战:绕过Cloudflare反爬的最新技术与完整代码详解

在互联网数据采集领域,越来越多的网站开始部署CDN和安全防护服务,其中 Cloudflare 是最为广泛使用的防护方案之一。它不仅为网站提供DDoS防护,还能通过JS挑战、验证码和行为分析来识别并拦截爬虫。这给爬虫工程师带来了极大挑战——如何在不违反网站服务条款的情况下,实现有效的数据采集?本文将分享Python领域绕过Cloudflare反爬的最新技术方法,结合最新流行库与自动化浏览器,帮助你攻克这一难题。绕过Cloudflare反爬不是一蹴而就,需结合多技术、多策略,持续迭代。

2201_76125261的博客 2628

线程池(ThreadPool):使用ExecutorService、ThreadPoolExecutor等线程池管理并发任务以及底层实现原理

核心线程数,当提交任务时,如果当前线程数小于核心线程数,即使线程池中有空闲线程,也会创建新的线程来执行任务。:线程池的最大线程数,当任务队列已满且线程数小于最大线程数时,线程池会创建新线程来执行任务。:非核心线程的空闲时间超过此时间后将被终止(如果当前线程数大于workQueue:任务队列,用于存放等待执行的任务。:有界队列,任务达到队列上限时,新的任务将被阻塞或拒绝。:无界队列,适合任务量较大的场景。:没有容量的队列,提交的任务必须直接交给线程执行,否则会创建新线程。

Flying_Fish_roe的博客 1835

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

JUC 之 ThreadPoolExecutor线程池【核心参数如何协同?线程管理方法在使用上的区别?有哪些方便线程池监控的方法?】

核心参数(corePoolSize, maximumPoolSize, keepAliveTime, milliseconds,runnableTaskQueue, RejectedExecutionHandler)如何协同?核心方法(execute、submit、shutdown、shutdownNow、isShutdown、isTerminaed)如何使用?有哪些线程池监控方法?

人生快意事,读的好书,觅得良友 931

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

线程池的使用

我们有两种常见的创建线程的方法,一种是继承Thread类,一种是实现Runnable的接口,Thread类其实也是实现了Runnable接口。但是我们创建这两种线程在运行结束后都会被虚拟机销毁,如果线程数量多的话,频繁的创建和销毁线程会大大浪费时间和效率,更重要的是浪费内存,因为正常来说线程执行完毕后死亡,线程对象变成垃圾!那么有没有一种方法能让线程运行完后不立即销毁,而是让...

DXINGYU的博客 376

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

ThreadPoolExecutor线程池使用

【代码】ThreadPoolExecutor线程池使用。

weixin_56868125的博客 133

异步线程池中,ThreadPoolTaskExecutor和ThreadPoolExecutor有什么区别?

异步线程池中,ThreadPoolTaskExecutor和ThreadPoolExecutor有什么区别?

技术小站 1143

JAVA线程池的原理及使用

JAVA线程池的原理及使用一,使用线程池的原因二 ThreadPoolExecutor类的介绍1、构造方法合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart...

瓶子君的博客 315

Android开发线程池管理类之ThreadPoolExecutor工具类

平常开发中网络请求自从Android4.0后强制要求放到子线程中避免主线程进行网络请求,一般很多人习惯直接通过new Thread的方法。不建议这样使用。我们用ThreadPoolExecutor线程池这个类创建比较好。所以有了下面的线程池工具类。 先来张JDK1.6的中文参数说明 package com.xiayiye.honorfirst.utils; import java.ut...

xiayiye5的博客 1578

Java基础之线程池基本使用

1.线程池类为java.util.concurrent.ThreadPoolExecutor, 常用构造方法为: ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,long keepAliveTime, TimeUnit unit,BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler) 2.使用线程池的好处: 降低资源消耗:通过重复利用已..

u012556114的博客 420

ThreadPoolExecutor线程池的使用

Java并发编程:线程池的使用 Java并发编程:线程池的使用   在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题:   如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。   那么有没有一种办法使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务?   在Java中可以通过线程池来达到这样的效果。今天我们就来详细讲解一下Java的

qq_40826814的博客 1319

Java线程池设计思想及使用demo

线程池中队列的出现,代表线程池使用的是事件驱动模型,当工作线程资源充足时,系统会将队列中的任务委派至对应线程处理(部分线程池无缓存队列);当没有可用线程时,可以根据配置等待或丢弃。如果当前线程池中的活跃线程数小于最大线程数,当所有线程处于工作状态时,会创建新的线程,直到活跃线程数等于最大线程数。待活跃线程空闲一定时间之后,会被回收。

qq_35316141的博客 1052

【线程池】线程池的7种创建方式,详细讲解

线程池(ThreadPool)是一种基于池化思想管理和使用线程的机制。它是将多个线程预先存储在一个“池子”内,当有任务出现时可以避免重新创建和销毁线程所带来性能开销,只需要从“池子”内取出相应的线程执行对应的任务即可。内存池(Memory Pooling):预先申请内存,提升申请内存速度,减少内存碎片。连接池(Connection Pooling):预先申请数据库连接,提升申请连接的速度,降低系统的开销。实例池(Object Pooling):循环使用对象,减少资源在初始化和释放时的昂贵损耗。

m0_46638350的博客 1万+

java线程池ThreadPoolExecutor使用

java线程池

qq_43456605的博客 2500

python队列线程池_Python线程池之ThreadPoolExecutor详解

1、什么是线程池线程池的基本思想是一种对象池,在程序启动时就开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源。2、使用线程池的好处减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。运用线程池能有效的控制线程最大并发数,可以根...

weixin_34980267的博客 2044
上一篇: xml解析工具类
下一篇: spring boot validation使用
刘彦青-Yannis
博客等级 码龄10年 1万+粉丝 234原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘彦青-Yannis

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值