Java线程池ThreadPoolExecutor应用(Spring Boot微服务)

2023-11-07

记录:475

场景:在Spring Boot微服务中使用Java线程池ThreadPoolExecutor。实现Runnable接口提交线程任务到线程池。

版本:JDK 1.8,Spring Boot 2.6.3。

1.使用注解配置线程池ThreadPoolExecutor

(1)说明

ThreadPoolExecutor,全称:java.util.concurrent.ThreadPoolExecutor。

使用@Bean("threadPoolExecutorHz")注解把线程池注入到Spring IOC容器中。

(2)代码

@Configuration
public class ThreadPoolConfig {
    @Bean("threadPoolExecutorHz")
    public ThreadPoolExecutor threadPoolExecutor(){
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                8,
                16,
                10,
                TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<Runnable>(10),
                new ThreadPoolExecutor.CallerRunsPolicy()
        );
       return threadPoolExecutor;
    }
}

(3)线程参数

corePoolSize: the number of threads to keep in the pool, even if they are idle, unless allowCoreThreadTimeOut is set

maximumPoolSize: the maximum number of threads to allow in the pool

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.

unit: the time unit for the keepAliveTime argument

workQueue: the queue to use for holding tasks before they are executed. This queue will hold only the Runnable tasks submitted by the execute method.

handler: the handler to use when execution is blocked because the thread bounds and queue capacities are reached

2.实现Runnable接口的线程任务类

(1)说明

提交给线程池任务,需实现Runnable接口。

Runnable接口的run方法里面就是线程具体执行的业务逻辑。

(2)代码

public class SportContestExecutor implements Runnable {
  private SportContest sportContest;
  public SportContestExecutor(SportContest sportContest) {
      this.sportContest = sportContest;
  }
  @Override
  public void run() {
      String eventName = sportContest.getTaskDto().getEventName();
      System.out.println("【线程: "+Thread.currentThread().getName()+",在直播: "+eventName+"】");
      this.sportContest.holdSportGame();
  }
}

3.线程具体业务逻辑类

(1)说明

本例线程执行的业务逻辑实现类均继承于同一个抽象类。因此,在Runnable接口的线程任务类中是基于抽象类编程。

(2)抽象类SportContest

全称:com.hub.example.p1.contest.SportContest

代码:

public abstract class SportContest {
    //赛事任务
    private TaskDto taskDto;
    //开场仪式
    public abstract String announceStart();
    //举行比赛
    public abstract ResultDto playGame();
    //颁奖仪式
    public abstract String announceEnd(ResultDto resultDto);
    //举行体育赛事
    public String holdSportGame() {
        String result01 = announceStart();
        ResultDto result02 = playGame();
        String result03 = announceEnd(result02);
        return result03;
    }
    public TaskDto getTaskDto() {
        return taskDto;
    }
    public void setTaskDto(TaskDto taskDto) {
        this.taskDto = taskDto;
    }
}

(3)实现类BadmintonContest

全称:com.hub.example.p1.contest.impl.BadmintonContest

代码:

public class BadmintonContest extends SportContest {
    public BadmintonContest(TaskDto taskDto){
        this.setTaskDto(taskDto);
    }
    @Override
    public String announceStart() {
        TaskDto taskDto = this.getTaskDto();
        System.out.println("举行羽毛球比赛入场仪式:");
        System.out.println("羽毛球比赛入场仪式步骤一: "+taskDto.getEventName()+"队员入场.");
        System.out.println("羽毛球比赛入场仪式步骤二: 裁判员、教练员等各就各位.");
        return "羽毛球比赛进行中";
    }
    @Override
    public ResultDto playGame() {
        TaskDto taskDto = this.getTaskDto();
        System.out.println("举行羽毛球比赛: "+taskDto.getContent()+",选手们在奋力搏击.");
        return ResultDto.builder().teamName("中国羽毛球队").content("男单决赛冠军").build();
    }
    @Override
    public String announceEnd(ResultDto resultDto) {
        System.out.println("举行羽毛球比赛颁奖仪式: ");
        System.out.println("羽毛球比赛颁奖步骤一: 为"+resultDto.getTeamName()+resultDto.getContent()+"颁发金牌.");
        System.out.println("羽毛球比赛颁奖步骤二: 升中华人民共和国国旗,奏中华人民共和国国歌.");
        return "羽毛球比赛圆满结束";
    }
}

(4)实现类DivingContest

全称:com.hub.example.p1.contest.impl.BadmintonContest

代码:

public class DivingContest extends SportContest {
    public DivingContest(TaskDto taskDto) {
        this.setTaskDto(taskDto);
    }
    @Override
    public String announceStart() {
        TaskDto taskDto = this.getTaskDto();
        System.out.println("举行跳水比赛入场仪式:");
        System.out.println("跳水比赛入场仪式步骤一: "+taskDto.getEventName()+"队员入场.");
        System.out.println("跳水比赛入场仪式骤二: 裁判员、教练员等各就各位.");
        return "跳水比赛进行中";
    }
    @Override
    public ResultDto playGame() {
        TaskDto taskDto = this.getTaskDto();
        System.out.println("举行跳水比赛: " + taskDto.getContent() + ",姑娘们在冲刺记录.");
        return ResultDto.builder().teamName("中国跳水队").content("女子10米台跳板决赛冠军").build();
    }
    @Override
    public String announceEnd(ResultDto resultDto) {
        System.out.println("跳水比赛举行颁奖仪式: ");
        System.out.println("跳水比赛举行颁奖仪式步骤一: 为"+resultDto.getTeamName()+resultDto.getContent()+"颁发金牌.");
        System.out.println("跳水比赛举行颁奖仪式步骤二: 升中华人民共和国国旗,奏中华人民共和国国歌.");
        return "跳水比赛圆满结束";
    }
}

4.把Runnable接口的线程任务类提交到线程池

(1)说明

Runnable接口的线程任务类需提交到线程池才能具体执行。

(2)代码

@Component("sportWorker01")
public class SportWorker01 {
    /**
     * 自动注入线程池
     * */
    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;

    /**
     * 把线程任务提交到线程池
     */
    public void holdGame() {
        SportContest tableTennis = createBean("com.hub.example.p1.contest.impl.BadmintonContest",
                TaskDto.builder().eventName("羽毛球球比赛").content("男单决赛").build());
        SportContestExecutor executor01= new SportContestExecutor(tableTennis);
        SportContest swimming = createBean("com.hub.example.p1.contest.impl.DivingContest",
                TaskDto.builder().eventName("跳水比赛").content("女子10米台跳板决赛").build());
        SportContestExecutor executor02= new SportContestExecutor(swimming);
        threadPoolExecutor.execute(executor01);
        ThreadUtil.sleep(1000);
        threadPoolExecutor.execute(executor02);
    }
    /**
     * 使用Java反射方式创建对象
     */
    public SportContest createBean(String className, TaskDto params) {
        try {
            Class<?> clazz = Class.forName(className);
            Constructor<?> constructor = clazz.getConstructor(TaskDto.class);
            SportContest sportContest = (SportContest) constructor.newInstance(params);
            return sportContest;
        } catch (Exception e) {
            return null;
        }
    }
}

5.测试示例

(1)说明

直接在SpringBoot的启动类的main函数中测试。

在执行完成SpringApplication.run(Example212Application.class)后,SpringBoot的环境已经创建完成。

(2)代码

@SpringBootApplication
public class Example212Application {
    public static void main(String[] args) {
        SpringApplication.run(Example212Application.class);
        SportWorker01 sportWorker01 = SpringUtil.getBean("sportWorker01");
        sportWorker01.holdGame();
    }
}

(3)输出结果

【线程: pool-1-thread-1,在直播: 羽毛球球比赛】
举行羽毛球比赛入场仪式:
羽毛球比赛入场仪式步骤一: 羽毛球球比赛队员入场.
羽毛球比赛入场仪式步骤二: 裁判员、教练员等各就各位.
举行羽毛球比赛: 男单决赛,选手们在奋力搏击.
举行羽毛球比赛颁奖仪式: 
羽毛球比赛颁奖步骤一: 为中国羽毛球队男单决赛冠军颁发金牌.
羽毛球比赛颁奖步骤二: 升中华人民共和国国旗,奏中华人民共和国国歌.
【线程: pool-1-thread-2,在直播: 跳水比赛】
举行跳水比赛入场仪式:
跳水比赛入场仪式步骤一: 跳水比赛队员入场.
跳水比赛入场仪式骤二: 裁判员、教练员等各就各位.
举行跳水比赛: 女子10米台跳板决赛,姑娘们在冲刺记录.
跳水比赛举行颁奖仪式: 
跳水比赛举行颁奖仪式步骤一: 为中国跳水队女子10米台跳板决赛冠军颁发金牌.
跳水比赛举行颁奖仪式步骤二: 升中华人民共和国国旗,奏中华人民共和国国歌.

6.辅助实体类

(1)说明

在实体类中使用注解@Data等来自lombok-1.18.24.jar。

(2)TaskDto

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class TaskDto implements Serializable {
    //赛事名称
    private String eventName;
    //活动内容
    private String content;
}

(3)ResultDto

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ResultDto implements Serializable {
    //竞赛队伍
    private String teamName;
    //比赛成绩
    private String content;
}

以上,感谢。

2023年9月13日

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java线程池ThreadPoolExecutor应用(Spring Boot微服务) 的相关文章

  • c++ 存储函数和参数列表以供以后使用

    所以我想通过用 C 编写一个小型线程池来挑战自己 并且我想尝试模仿 std thread 的易用方式 您可以创建一个线程并作为参数发送一个函数和参数与 pthreads 之类的函数相比 pthreads 强制您将 void 作为该函数的唯一
  • IIS 工作线程与 Web 应用程序线程

    我正在维护一个ASP NET Core需要重复运行一些后台线程的 Web 应用程序 我知道这不是一个好的设计 但目前我必须以最小的努力解决它的主要问题 现在我想知道我是否应该担心网络服务器处理用户http请求 问题很简单 但我找不到任何明确
  • 有没有办法确保线程分配给指定的对象集?

    我们正在开发一个应用程序 其中一组对象可能会受到来自 3 个不同源的消息的影响 每条消息 来自任何源 都有一个对象作为其目标 每个消息接收器将在其自己的线程上运行 我们希望消息的处理 接收后 尽可能高速 因此针对目标对象的消息处理将由线程池
  • ThreadPool.SetMinThreads 和 SetMaxThreads 以及核心数量

    我目前正在研究 Redis 为了调整其功能 我们需要更改 ThreadPool 的设置 特别是 Worker IOC 线程的最小数量 我们在 Azure Web 角色中托管应用程序 并将其一部分托管在辅助角色中 阅读 asp net 的文档
  • 多线程Windows服务的线程库[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 保证池中仅执行一个具有特定 id 值的 Runnable 对象的设计模式

    假设我有一个有序列表Runnable要执行的对象ExecutorService My Runnable对象有一个userID已提交 假设我有关于20不同的userId s and 10是池中的线程数 ExecutorService目的 确保
  • asp.net 中的后台工作者(线程池)

    我有一个 ASP NET Web 表单 它将大约 25 30 个项目 包含用户从表单发出后续请求时所需的信息 写入自定义缓存中 目前 所有这些都是在主线程上同步发生的 但在较高负载下 addcache 正在成为瓶颈 如何在后台运行此任务而不
  • 如何解决Java错误“pool-1-thread-xxxx”java.lang.OutOfMemory

    我搜索了有关此问题的帖子 但没有看到像我这样的情况 我的 java 控制台显示错误消息 pool 1 thread xxxx java lang OutOfMemory如下图 红线 CPU 使用率 绿线 内存使用情况 我增加了内存6G to
  • java中线程池的类型[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 java中的线程池有哪几种类型 我需要实现一个强大的多线程应用程序 该应用程序使用大量计算 我应该使用哪个线程池 java中有多种线程
  • 如何检测scala执行上下文耗尽?

    我的 Playframework 应用程序有时没有响应 我想在运行时检测到这一点 记录有关当前在耗尽的执行上下文上运行的内容的信息 实现这一目标的最佳策略是什么 我考虑过将小型可运行对象发布到执行上下文 如果它们没有及时执行 我会记录一条警
  • ExecutorService workStealingPool 和取消方法

    您能想到为什么这段代码不起作用并且总是输出 完成 但第二个示例可以正常工作的任何原因吗 我正在使用最新的 JDK 8u45 public static class MyClass implements Runnable Override p
  • ASP.Net 中线程敏捷性的含义是什么?

    我正在阅读一篇有关 HttpContext 和 CallContext 的文章并查看线程敏捷性 这是什么意思 这意味着 IIS 可以自由地使用多个线程来处理单个请求 尽管不是并行的 基本上 IIS 尝试异步执行 I O 操作 从而在操作期间
  • 如何在 ASP.net MVC 中正确执行异步方法?

    如何从控制器方法内执行异步方法并返回 HttpStatusCodeResult 200 而异步委托不会提前终止其执行 我正在开发一个 asp net 应用程序 我的家庭控制器的一个操作需要很长时间才能运行 10 30 秒 我想返回 Http
  • 如何使用java.util.concurrent包实现后台线程?

    这是我首先使用的代码 但在最新的 Android 版本中AsyncTask类已被弃用并且 因此它没有响应 然后我使用了Thread类 但该类也不起作用 我想要与我得到的结果相同的结果AsyncTask班级 我知道我必须使用 java uti
  • 如何解决 MongoWaitQueueFullException?

    我运行一个java程序 它是一个线程执行程序 它将数千个文档插入到mongodb中的表中 我收到以下错误 Exception in thread pool 1 thread 301 com mongodb MongoWaitQueueFul
  • 有没有好的带有 TaskExecutor 的 Spring 线程示例? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我试图了解如何在使用 Spring 进行事务管理的 Java 应用程序中实现线程 我在中找到了 Tas
  • 为什么C++标准库中没有线程池? [复制]

    这个问题在这里已经有答案了 自 C 11 以来 C 中并行 并发编程工具的数量激增 线程 异步函数 并行算法 协程 但是流行的并行编程模式又如何呢 线程池 https en wikipedia org wiki Thread pool 据我
  • 使用Python pool.map让多个进程对列表执行操作

    我试图启动 6 个线程 每个线程从列表文件中获取一个项目 将其删除 然后打印该值 from multiprocessing import Pool files a b c d e f def convert file process fil
  • 多线程Spring-boot控制器方法

    因此 我的应用程序 spring boot 运行速度非常慢 因为它使用 Selenium 来抓取数据 处理数据并显示在主页中 我遇到了多线程 我认为它对我的应用程序很有用 可以让它运行得更快 但是教程似乎显示在带有 main c 的普通 j
  • ThreadPool.SetMinThreads 不创建任何新线程

    我想弄清楚到底有什么影响ThreadPool SetMinThreads makes 根据官方文档 https learn microsoft com en us dotnet api system threading threadpool

随机推荐

  • C#串口SerialPort常用属性方法

    SerialPort 属性 BaudRate 获取或设置波特率 BytesToRead 得到 接收到数据的字节数 BytesToWrites 得到送往串口的字节数 DataBits 获取或设置数据位 IsOpen 获取一个值 判断串口是否打
  • SpringBoot结合Redis将Token存入缓存中进行登录

    将登录的Token存储在Redis中可以带来以下好处 提高安全性 将Token存储在Redis中 比将Token保存在本地Cookie或浏览器存储中更加安全 因为攻击者无法访问您的服务器上存储的Token 此外 由于Redis支持设置过期时
  • selenium 使用及定位

    使用find element by 方法只需导入 from selenium import webdriver 使用 find element 方法除了导入 from selenium import webdriver 还要导入 from
  • Java OpenJDK 8u382 Windows x64 Installer

    文章目录 一 Azul 二 Adopt 三 IBM 四 Oracle 一 Azul WEB Page Download Azul Zulu Builds of OpenJDK Windows installer Azul Zulu Buil
  • 干电池升压5V,功耗比较低

    干电池升压5V 功耗10uA PW5100干电池升压5V芯片 输出电容 所以为了减小输出的纹波 需要比较大的输出电容值 但是输出电容过大 就会使得系统的 反应时间过慢 成本也会增加 所以建议使用一个 22uF 的电容 或者两个 22uF 的
  • Java动态规划硬币问题最优值和最优解

    给定不同面额的硬币coins和一个总金额amount 计算并输出可以凑成总金额所需的最少的硬币个数和使用的硬币 网上介绍动态规划的文章已经很多了 我的这篇文章分析了我自己分析硬币问题的算法在二维数组的效能分析 其中用了Intellij ID
  • maven项目如何加载不同的配置文件

    疑惑 公司项目 本地启动时取用默认路径的下的配置文件 而当maven打包时取用另一文件路径下的配置文件 解决过程 首先查找公司项目代码中是否控制本地启动和服务器启动时使用的配置文件不同 但是发现并不是 最后考虑是否是maven打包加载时已经
  • tiktok新号发布的视频播放量为零解决方案

    tiktok新号发布的视频播放量为零解决方案 大家好 我是项柚 一个专注于讨论TikTok玩法的跨境电商自媒体人 每天不断输出干货给需要的朋友 首先我们先来看下0播放的原因 一 伪装度不够 首先我们在打开TikTok之前 你的伪 装度必须是
  • docker容器内安装git服务端

    创建容器 privileged 获得完整的root权限 usr sbin init 启动容器执行的第一个命令 以便可以使用systemctl命令 将容器的ssh服务22端口映射到宿主的65002端口 docker run itd privi
  • 深入学习jquery源码之noConflict()

    深入学习jquery源码之noConflict jQuery noConflict extreme 概述 运行这个函数将变量 的控制权让渡给第一个实现它的那个库 执行 var jq noConflict 后 将不再控制当前的jQuery 而
  • Spring boot短信验证登录

    一 短信验证码业务 我用的是第三平台的短信服务 当用户点击发送验证码 会调用短信平台接口 从而给手机发验证码 流程如下 c 首先需要工具类 来发送验证码 public class DXMessageUtil public static Bo
  • 【05】MySQL:日志管理

    写在前面的话 日志是作为用户排查服务问题的重要依据 在 MySQL 中日志可以分为几类 各自产生着不同的作用 如 error log bin log slow log 等 很多时候优化数据库的优化来源就是日志 错误日志 error log
  • JAVA-数组

    数组 概念 用于存储具有相同数据类型的容器称之为数组 可以使用统一的标识符 变量名进行管理 数据既可以存储基本数据类型也可以存储引用数据类型 可以存储任意类型的数据 数组的使用 声明 声明 与变量声明类似 在相应位置声明一个变量用于存储指定
  • 16. 线性代数 - 矩阵的性质

    文章目录 神经网络的矩阵 向量 矩阵的性质 Hi 你好 我是茶桁 根据上一节课的预告 咱们这节课要进入神经网络中 看看神经网络中的矩阵 向量 然后再来详细了解下矩阵的性质 毕竟咱们的课程并不是普通的数学课 而是人工智能的数学基础 那为什么人
  • java按钮新建窗口_java中如何创建一个登录窗口,有一个按钮(或是单选框)为不再? 爱问知识人...

    建一个本地配置文件保存参数 以后每次读取 登录时如果打钩了 写入不再显示的参数 public void writeinfo throws IOException File file new File c info inf if file e
  • MySQL约束

    概述 什么是MySQL约束 约束是作用于表中字段上的规则 用于限制存储在表中的数据 约束有什么作用 保证数据库中数据的正确 有效性和完整性 分类 约束 描述 关键字 非空约束 限制该字段的数据不能为null NOT NULL 唯一约束 保证
  • 军衔系统与服务器人数,经验越打越少?CSGO个人资料军衔(等级)介绍

    本文将为CSGO玩家们详细介绍CSGO个人资料军衔 经验等级 系统 包括解释为什么经验越打越少 CSGO个人资料军衔系统于2015年5月26日随血猎大行动一同引入 玩家可以在官方服务器任何模式游戏获得经验 XP 并升级 与水平组等级 段位
  • Ant-design-vue框架学习。

    1 安装教程 npm install ant design vue save 2 运用vue cli3 0版本搭建脚手架 3 样式布局layout插件布局快速实现整体布局 4 lib flexible实现屏幕适配 安装 npm instal
  • Tomcat

    关于Tomcat和Tomcat的面试问题 一 Tomcat的缺省是多少 怎么修改 Tomcat的缺省端口号是8080 修改Tomcat端口号 1 找到Tomcat目录下的conf文件夹2 进入conf文件夹里面找到server xml文件3
  • Java线程池ThreadPoolExecutor应用(Spring Boot微服务)

    记录 475 场景 在Spring Boot微服务中使用Java线程池ThreadPoolExecutor 实现Runnable接口提交线程任务到线程池 版本 JDK 1 8 Spring Boot 2 6 3 1 使用注解配置线程池Thr