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微服务) 的相关文章

  • 高处理器使用率下的 WCF 和线程池响应能力

    我们在控制使用 WCF 发送启动 停止命令的长时间运行进程时遇到问题 问题似乎是当CPU负载较高时WCF不响应请求 不幸的是 对于相关应用程序来说 尽可能多的内核上的高 CPU 是必要的 因为它需要执行大量的数值计算 该问题是否与使用 WC
  • Web 服务中的 ThreadPool.QueueUserWorkItem 用于“即发即忘”任务

    这是 ASP NET ASMX Web 服务 NET Framework 4 0 在 Web 服务中 我想在另一个线程上执行一个方法 例如 Fire and Forget 以便 Web 服务返回一些价值立即响应网站 Web 服务立即将响应返
  • CherryPy、线程和成员变量;潜在的问题?

    假设我有以下简单的类 import cherrypy import os class test test member 0 def init self return def index self self test member self
  • WPF:尽管使用了 Dispatcher.BeginInvoke,但访问绑定的 ObservableCollection 仍失败

    我有以下内容 public ICollectionView Children get Determining if the object has children may be time consuming because of netwo
  • 增强线程池

    我的应用程序需要一个线程池 并且我想尽可能依赖标准 C 11 或 boost 的东西 我意识到有一个非官方的 boost线程池类 它基本上解决了我所需要的 但是我宁愿避免它 因为它不在boost库本身中 为什么它仍然不在核心库中很多年 在此
  • c++ 存储函数和参数列表以供以后使用

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

    我正在尝试捕获像这样的期货中未捕获的异常CompletableFuture runAsync gt throw new RuntimeException 我的目标是当开发人员忘记处理这些异常时 让它们不再沉默 Calling get or
  • C++ 阻塞工作队列

    这个问题应该比我上几个简单一点 我在我的程序中实现了以下工作队列 Pool h tpool class It s always closed glasses ifndef POOL H define POOL H class tpool p
  • .NET Threadpool工作线程和异步IO线程

    好的 据我了解 NET 线程池维护着许多后台线程 准备用于某种任务 Get SetMinThreads 和 Get SetMaxThreads 方法包含两个可以返回或调整的参数 根据MSDN http msdn microsoft com
  • 使用 Spring Boot 异步自定义 ThreadPoolTask​​Executor

    我有一个 Spring Boot 应用程序 负责通过 REST 应答请求 我还推送有关我的应用程序调用的指标 由于这是一项单独的任务 并且我必须立即响应用户 因此我希望异步发布该指标 所以我用过 ThreadPoolTaskExecutor
  • 如何使用 ExecutorService Java 减少到达 Runnable 类的 run 方法的时间延迟

    我试图实现一个实时执行应用程序 其中按钮单击事件将任务分配给 Thread 该任务将调用MIDI方法播放一些音乐 单击按钮时必须立即开始播放音乐 并有一小段延迟 midi代码在Runnable类的run方法中实现 但是要在按钮单击事件本身发
  • 线程池是如何工作的,以及如何在像 NodeJS 这样的 async/await 环境中实现它?

    我需要运行一个函数int f int i 有 10 000 个参数 由于 I O 时间的原因 执行大约需要 1 秒 在像Python这样的语言中 我可以使用线程 或者async await 我知道 但是我稍后会谈到 来并行化这个任务 如果我
  • 停止多线程 Windows 服务

    我在 Net 3 5 中有一个多线程 Windows 服务 当创建多个线程时 我在正确停止该服务时遇到了一些麻烦 该服务过去只创建一个线程来完成所有工作 我只是将其更改为多线程 它工作得很好 但是当服务停止时 如果有多个线程正在执行 它将挂
  • WCF 服务是否使用多个线程来处理传入请求?

    如何确保 WCF 服务使用 ThreadPool 中的线程来处理传入消息 目前简单的方法调用如 return null 处理另一个请求时大约需要 45 秒 以下是我注释服务类别的方式 ServiceBehavior ConcurrencyM
  • 使用 ThreadPool Python 时的最大池大小

    我正在使用 ThreadPool 来实现多处理 使用多处理时 池大小限制应等于 CPU 核心数 我的问题 使用 ThreadPool 时 池大小限制应该是 CPU 核心数吗 这是我的代码 from multiprocessing pool
  • 是否可以使用多线程而不需要一遍又一遍地创建线程?

    首先 再次感谢所有已经回答我问题的人 我不是一个经验丰富的程序员 这是我第一次体验多线程 我有一个与我的问题非常相似的例子 我希望这可以缓解我们的情况 public class ThreadMeasuring private static
  • 分析 Windbg 中 !threadpool 和 !threads 的输出

    我已经在四台服务器上生成了转储 并正在分析 threadpool 和 threads 的输出 我注意到以下输出大致一致 0 024 gt threadpool CPU utilization 0 Worker Thread Total 2
  • 重写线程池中线程的中断方法

    假设我有这个 class Queue private static ExecutorService executor Executors newFixedThreadPool 1 public void use Runnable r Que
  • 了解 PerfView 中的 BLOCKED_TIME

    我们怀疑在运行几个 ASP NET Core API 和几个 NET Core 控制台的服务器上遇到线程池饥饿的情况 当我们怀疑线程池匮乏问题时 我在我们的一台服务器上运行了 perfview 然而 我在分析结果时遇到了一些麻烦 I ran
  • C# 是否可以中断 ThreadPool 内的特定线程?

    假设我已将一个工作项排入队列ThreadPool 但是如果没有要处理的数据 从BlockingQueue 如果队列为空并且队列中不再有工作 那么我必须调用Thread Interrupt方法 如果我想中断阻塞任务 但是如何用 a 做同样的事

随机推荐

  • 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