【Java进阶】Java线程池ThreadPoolExecutor的使用详解以及SpringBoot下如何使用线程池

【多线程编程】--任务调度@Scheduled、ScheduledThreadPoolExecutor、quartz、xxl-job 目录一、springboot集成@Scheduled注解1.1、集成@Scheduled注解方法1.2、集成@Scheduled注解优劣点1.3、集成@Scheduled注解改进1.4、集成@Scheduled注解优缺点汇总二、springboot使用ScheduledThreadPoolExecutor定时调度2.1、ScheduleAtFixedRate方法2.2、ScheduleWithFixedDelay方法三、springboot集成quartz3.1、简单实现3.2、quartz优缺点四、任务调 阅读详情

1.应用场景

为了使线程池的使用更加的规范,同时合理的规划线程的数量,避免资源消耗。

2.代码理解

下面是ThreadPoolExecutor的构造函数。

    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.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

参数的含义介绍

参数含义
corePoolSize指定了线程池中的线程数量,它的数量决定了添加的任务是开辟新的线程去执行,还是放到workQueue任务队列中去
maximumPoolSize指定了线程池中的最大线程数量
keepAliveTime当线程池中空闲线程数量超过corePoolSize时,多余的线程会在多长时间内被销毁
unitkeepAliveTime的单位
workQueue任务队列,被添加到线程池中,但尚未被执行的任务
threadFactory线程工厂,用于创建线程
handler拒绝策略;当任务超出线程池数量时,如何拒绝任务

2.1 workQueue队列

队列类名介绍
直接提交队列SynchronousQueue没有容量,执行一个插入就会阻塞,删除就会唤醒,此时,如果有多条线程任务进来,会直接启用maximumPoolSize对应的线程数量,超出的直接执行拒绝策略
有界的任务队列ArrayBlockingQueue若有新的任务加入线程,线程池会创建新的线程,直到创建的线程达到corePoolSize,再有线程进来,会存在队列当中,如果队列存满,会继续创建线程直到达到maximumPoolSize之后执行拒绝策略
无界的任务队列LinkedBlockingQueue线程池的任务队列可以无限制的添加新的任务,而线程池能够创建的最大的线程数量就是corePoolSize,maximumPoolSize这个参数等于已经无效了
优先任务队列PriorityBlockingQueue在任务中设置优先级,队列会根据优先级进行任务的重排,执行优先级高的任务,任务的执行数量不会超过corePoolSize

2.2 拒绝策略

我们这里只探讨有界队列的情况,因为只有有界队列才可能出现超出队列且超出最大线程数量的情况。

策略含义
AbortPolicy策略该策略会直接抛出异常,阻止系统正常工作
CallerRunsPolicy策略如果线程池的线程数量达到上限,该策略会把任务队列中的任务放在调用者线程当中运行
DiscardOledestPolicy策略该策略会丢弃任务队列中最老的一个任务,也就是当前任务队列中最先被添加进去的,马上要被执行的那个任务,并尝试再次提交
DiscardPolicy策略该策略会默默丢弃无法处理的任务,不予任何处理。当然使用此策略,业务场景中需允许任务的丢失

2.3 自定义线程工厂

public void executeExecutor(){
            new ThreadPoolExecutor(1, 2, 1000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10), new ThreadFactory() {
                @Override
                public Thread newThread(Runnable r) {
                    Thread thread = new Thread(r,r.hashCode() + "");
                    return thread;
                }
            },new ThreadPoolExecutor.CallerRunsPolicy());
        }

2.4 自定义拒绝策略

new ThreadPoolExecutor(1, 2, 1000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),Executors.defaultThreadFactory(), new RejectedExecutionHandler() {
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                System.out.println(r.toString()+"执行了拒绝策略"); 
            }
        });

3.SpringBoot下使用线程池

spring-context包下有一个ThreadPoolTaskExcecutor

@Configuration
public class ThreadPoolConfig
{
    // 核心线程池大小
    private int corePoolSize = 10;

    // 最大可创建的线程数
    private int maxPoolSize = 20;

    // 队列最大长度
    private int queueCapacity = 1000;

    // 线程池维护线程所允许的空闲时间
    private int keepAliveSeconds = 300;

    @Bean(name = "threadPoolTaskExecutor")
    public ThreadPoolTaskExecutor threadPoolTaskExecutor()
    {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setMaxPoolSize(maxPoolSize);
        executor.setCorePoolSize(corePoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setKeepAliveSeconds(keepAliveSeconds);
        // 线程池对拒绝任务(无线程可用)的处理策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }
}

使用

@Service
public TestServiceImpl implements TestService{

	@Autowird
	private ThreadPoolTaskExecutor threadPoolTaskExecutor;

	public void test(){
		threadPoolTaskExecutor.execute(new Task())
	}

}

还有一个线程池类可能也会用到,就是执行定时任务的线程池ScheduledThreadPoolExecutor
,SpringBoot中注入Bean如下

@Configuration
public class ThreadPoolConfig
{
    // 核心线程池大小
    private int corePoolSize = 50;
/**
     * 执行周期性或定时任务
     */
    @Bean(name = "scheduledExecutorService")
    protected ScheduledExecutorService scheduledExecutorService()
    {
        return new ScheduledThreadPoolExecutor(corePoolSize,
                new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build())
        {
            @Override
            protected void afterExecute(Runnable r, Throwable t)
            {
                super.afterExecute(r, t);
                Threads.printException(r, t);
            }
        };
    }
}

用法如下

@Service
public TestServiceImpl implements TestService{

	@Autowird
	private ScheduledExecutorService scheduledExecutorService;

	public void test(){
		scheduledExecutorService.scheduleAtFixedRate(new Task(),0,30,TimeUnit.Seconds);
		// 0表示首次执行任务的延迟时间
		//30表示执行任务的时间间隔
		//TimeUnit.Seconds表示时间的单位
	}

}
SpringBoot定时任务@Scheduled的多线程使用 Scheduled是Spring框架中的一个注解,它可以用于配置定时任务,使得方法可以按照规定的时间间隔定时执行。在使用该注解时,我们可以指定任务的执行时间、循环周期、并发数等参数,从而实现定时任务的功能。在Spring Boot中,@Scheduled注解可以直接应用于方法上。通过以上的分析,我们可以了解到:虽然@Scheduled注解能够非常方便地实现定时任务的功能,但是它也存在一些多线程的问题。为此,需要注意到这些问题,并采取相应的措施来避免它们的出现。 阅读详情

相关推荐

Java中的线程池ThreadPoolExecutor

Java中创建线程的方法有四种,分别为继承Thread类,实现Runnable接口,实现Callable接口和通过线程池。在实际开发中,我们最常用的就是线程池的方法,因为利用线程池我们可以重复利用线程,减少每次创建线程所带来的额外开销;同时使用线程池也方便我们维护管理线程信息;此外,线程池的存在也可以帮助我们避免出现因为代码bug导致的无限创建线程导致系统资源耗尽等问题。 Java中通过使用ThreadPoolExecutor来创建管理线程池,而Spring框架中使用ThreadPoolTaskExecu

qq_40076948的博客 1149

动态注册bean到spring容器中

spring动态注册bean到spring容器中

haohaounique的博客 763

线程池详解:在SpringBoot中的最佳实践

Component@Scheduled(fixedRate = 60000) // 每分钟记录一次logThreadPoolStatus("自定义线程池", executor);// 监控ThreadPoolTaskExecutorlogThreadPoolStatus("任务执行线程池", tpExecutor);// 活跃线程数// 当前线程数// 核心线程数// 最大线程数// 已完成任务数// 总任务数// 队列大小log.info(

Dong雨的博客 2870

SpringBoot异步调用原理与生产实践指南

异步编程是现代高并发系统的核心技术,其核心原理是通过线程池复用避免请求线程阻塞。SpringBoot通过@Async注解和TaskExecutor体系提供了开箱即用的异步支持,配合线程池参数调优可显著提升系统吞吐量。在电商秒杀、物流跟踪等典型场景中,合理运用异步处理能将响应时间降低90%以上。本文深入解析线程池配置、事务边界处理等工程实践要点,并特别针对物流系统等高频场景给出性能优化方案,涵盖从Java原生线程池到虚拟线程等前沿技术。

weixin_33462167的博客 91

SpringBoot中使用Spring自带线程池ThreadPoolTaskExecutor与Java8CompletableFuture实现异步任务示例

关于线程池的使用:项目开发中多使用SpringBoot,Spring中有个自带的线程池ThreadPoolTaskExecutorSpring 通过任务执行器(TaskExecutor)来实现多线程和并发编程,使用ThreadPoolTaskExecutor实现一个基于线程池的TaskExecutorThreadPoolTaskExecutor是spring core包中的,而ThreadPoolExecutor是JDK中的JUC。

BADAO_LIUMANG_QIZHI的博客 3285

ElasticSearch集群搭建

docker安装es集群

weixin_46562226的博客 2024

java线程池详解

1.线程池使用场景? java中经常需要用到多线程来处理一些业务,我们非常不建议单纯使用继承Thread或者实现Runnable接口的方式来创建线程,那样势必有创建及销毁线程耗费资源、线程上下文切换问题。同时创建过多的线程也可能引发资源耗尽的风险,这个时候引入线程池比较合理,方便线程任务的管理。java中涉及到线程池的相关类均在jdk1.5开始的java.util.concurrent包中,涉及到的几个核心类及接口包括:Executor、Executors、ExecutorService、ThreadPo

人生就像一场戏 3万+

uniapp 使用摄像头 live-pusher (APP)

uniapp 中开发 app 时使用live-pusher踩过的坑

随身笔记 1万+

在Springboot中使用ThreadPoolExecutor线程池

在springboot项目中如果需要用到ThreadPoolExecutor线程池的话是非常方便的。比使用java并发包中的Executors都还方便很多。 实际上spring中的线程池ThreadpoolExecutor只是对java并发包中的线程池的封装。这样便于在spring环境中快速使用。通过几个注解即可,降低了对代码的侵入性。 1.ThreadPoolExecutor配置 在本文中,将使用spring提供的ThreadPoolTaskExecutor进行配置。 1.1 yml中的配置参数 配置参数

dhaibo1986的专栏 3649

AI大模型学习(13)小白也能学会的10分钟豆包大模型的python教程1

豆包AI大模型API是字节跳动推出的智能对话接口服务,开发者可以通过简单的HTTP请求调用强大的AI能力,实现智能问答、内容生成等功能。

isoft888的专栏,致力于C#/python分享物联网、大数据,神经网络的等领域,欢迎讨论交流! 1001

HC32 CAN通信

qqa

zhaopenglihui的博客 5431

Java并发编程 之线程池ThreadPoolExecutor详解

文章目录线程池定义使用案例ThreadPoolExecutor 参数详解Executors 线程池工厂工具类 线程池定义 java.util.concurrent.ThreadPoolExecutor 使用案例 package fireland.yangqian.thread; import java.util.Random; import java.util.concurrent.Execu...

const_ 8016

java.sql.SQLIntegrityConstraintViolationException: #23000

java.sql.SQLIntegrityConstraintViolationException: #23000**异常信息****异常原因****解决方法** 异常信息 ### Cause: java.sql.SQLIntegrityConstraintViolationException: #23000 ; #23000; nested exception is java.sql.SQLIntegrityConstraintViolationException: #23000] with root c

123 4351

SpringBoot使用线程池

SpringBoot使用线程池 软件环境 名称 版本号 jdk 1.8 springboot 2.1.6 maven 3.3.9 1.Java中创建线程池 只会介绍java中线程池的核心类ThreadPoolExecutor,其他用法请自行查询 1.1 ThreadPoolExecutor类介绍 jdk1.8 源码 删减部分内容 package java...

Cain的博客 2万+

OmniDrive(3):逐行代码详解

模型效果: 端到端联合规划与推理 接下来,简单介绍下训练的配置 1.1 模型配置 模型基于sparse query based的3D Bev感知框架StreamPetr ,用query来编码动态目标(如车辆、行人)和静态地图元素(如车道线)。(1) tran、test和val数据配置 指定真值的文件路径: ann_file 指定输出处理的pipeline: 训练使用, test 和val使用 指定是否需要时序训练seq_mode (2)数据处理pipeline 自定义的Dataset 通过类实现,训

@bangbang的博客 719

如何通过 GitHub Actions 使用 SSH 自动化部署到阿里云 ECS 实例

通过 GitHub Actions 和 SSH 自动化部署,可以显著提高你的开发效率和部署的可靠性。本文介绍了如何生成 SSH 密钥、将公钥添加到阿里云 ECS 实例、将私钥添加到 GitHub Secrets,以及编写 GitHub Actions 工作流来实现自动化部署。希望这篇文章对你有所帮助!

吃面不喝汤的博客 1510

SpringBoot使用线程池之ThreadPoolTaskExecutor和ThreadPoolExecutor

文章目录前言预热:ThreadPoolExecutor构造器四种拒绝策略ThreadPoolExecutor.AbortPolicyThreadPoolExecutor.CallerRunsPolicyThreadPoolExecutor.DiscardPolicyThreadPoolExecutor.DiscardOldestPolicy工作流程正题:ThreadPoolTaskExecutor继承关系成员变/常量初始化方法高潮:SpringBoot中使用ThreadPoolTaskExecutor创建S

FBB360JAVA的博客 5465

【QNX Hypervisor 2.2 用户手册】2.6 处理qvm终止

你可以注册通知,以在qvm进程实例退出时得到通知。这样你就可以采取相应的措施来响应这种终止事件。

从0到1,突破自己 1103

SpringBoot中使用ThreadPoolExecutor和ThreadPoolTaskExecutor线程池的方法和区别

SpringBoot中使用ThreadPoolExecutor和ThreadPoolTaskExecutor的方式和区别

smiling 5346

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Java线程池和SpringBoot异步线程池

目录 一、SpringBoot异步线程池 1、定义线程池 2、线程池的使用 二、ThreadPoolTaskExecutor和ThreadPoolExecutor区别 1、ThreadPoolExecutor的处理流程  2、四种Reject预定义策略 三、Java线程池 1、使用线程池的优势 2、什么是阻塞队列? 3、线程池为什么要是使用阻塞队列? 4、如何配置线程池? ...

swadian2008的博客 2340

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

一妹子揭露美团面试中一些不愉快的事情(Java 岗)

文章中涉及到的知识点我都已经整理成了资料,录制了视频供大家下载学习,诚意满满,希望可以帮助在这个行业发展的朋友,在论坛博客等地方少花些时间找资料,把有限的时间,真正花在学习上,所以我把这些资料,分享出来。相信对于已经工作和遇到技术瓶颈的朋友们,在这份资料中一定都有你需要的内容。《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

2401_84412961的博客 975

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

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

线程池、及Springboot线程池实践

线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。

jainszhang的博客 1721

Java线程池ThreadPool详解

Java线程池ThreadPool详解1. 线程池概述1.1 线程池简介1.2 线程池特点1.3 线程池解决的问题2. 线程池原理分析2.1 线程池总体设计2.6 线程池流转状态2.2 线程池执行流程2.3 线程池核心参数2.4 线程池饱和策略2.5 线程池阻塞队列2.7 关闭线程池3. 线程池工具类4. Executors创建线程池注意事项5. 线程池手动创建6. SpringBoot创建线程池 1. 线程池概述 1.1 线程池简介 线程池(Thread Pool)是一种基于池化思想管理线程的工具,经常出

靖节先生的博客 8488

线程池ThreadPoolExecutor整合Springboot使用

pom.xml 为了在application.properties自定义的配置有提示 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>tru

qq_35310348的博客 2449
上一篇: 【SpringBoot】SpringBoot下多数据源的实现,利用AbstractRoutingDataSource抽象类
下一篇: 【Docker】Centos7.6和Windows10下安装Docker
JeffHan^_^
博客等级 码龄7年 1万+粉丝 134原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

JeffHan^_^

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

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

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

打赏作者

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

抵扣说明:

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

余额充值