Java线程池ExecutorService和Executors应用(Spring Boot微服务)

记录:476

场景:在Spring Boot微服务中使用ExecutorService管理Java线程池。使用Executors创建线程池。使用Runnable接口实现类提交线程任务到线程池执行。

版本:JDK 1.8,Spring Boot 2.6.3。

1.线程和线程池基础

JDK自带线程和线程池包位置:java.util.concurrent.*,以及java.lang.Runnable和java.lang.Thread在java.lang.*中。

1.1线程接口Runnable

接口全称:java.lang.Runnable。

接口注释:The Runnable interface should be implemented by any class whose instances are intended to be executed by a thread.

说明:提交给线程执行的类需实现Runnable接口。该接口只有一个抽象方法public abstract void run()。具体业务逻辑如需被线程调用的话,必须在此run方法内调用业务逻辑。

1.2线程Thread

类全称:java.lang.Thread。

类注释:A thread is a thread of execution in a program. The Java Virtual Machine allows an application to have multiple threads of execution running concurrently.

说明:线程java.lang.Thread实现了java.lang.Runnable接口。在java.lang.Thread中维护了JVM中对线程的属性和方法的操作。方法包括线程创建、初始化、启动、运行、停止等。属性包括

线程名称、优先级、守护进程标志位、线程组、线程本地变量等。

接收Runnable线程任务方式:一般在创建Thread线程对象时,在有参构造函数的输入参数中传入自定义线程任务(实现Runnable接口的对象)。比如:public Thread(Runnable target)。

1.3线程池

(1)接口

java.util.concurrent.Executor,线程池顶层接口,只有一个抽象方法void execute(Runnable command)。此方法执行提交给线程池已实现Runnable接口的线程任务。

java.util.concurrent.ExecutorService,线程池接口,实现java.util.concurrent.Executor接口。此接口中主要提供线程池提交任务的submit方法、和invokeAll方法等方法。

(2)抽象类

java.util.concurrent.AbstractExecutorService,线程池默认实现方式,在AbstractExecutorService中提供默认的实现ExecutorService接口的方式。

(3)实现类

java.util.concurrent.ThreadPoolExecutor,线程池实现类。

主要是对线程池的创建、运行、维护等方面管理。

属性包括运行状态、线程池大小、线程池任务数量、线程池工厂类ThreadFactory、线程池工作线程、线程池同步线程锁、线程池任务队列BlockingQueue<Runnable> workQueue等。

方法包括一序列有参构造函数创建线程池、线程池执行任务方法void execute(Runnable command),以及获取线程池相关属性的get方法和设置线程池相关属性的set方法。

1.4线程池创建工具类Executors

全称:java.util.concurrent.Executors。

说明:在Executors中包括一序列创建线程池的静态方法,此类构造方法是private类型,因此不可被实例化。

类方法包括如下,可按需选择。

public static ExecutorService newFixedThreadPool(int nThreads);
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory);
public static ExecutorService newWorkStealingPool();
public static ExecutorService newWorkStealingPool(int parallelism)
public static ExecutorService newSingleThreadExecutor();
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) ;
public static ExecutorService newCachedThreadPool();
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory);
public static ScheduledExecutorService newSingleThreadScheduledExecutor();
public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory);
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize);
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory);

1.5其它

(1)线程专用的一些类

java.lang.Runnable

java.util.concurrent.Callable

java.util.concurrent.Future

java.util.concurrent.FutureTask

(2)线程工程类

线程池工厂(接口)

java.util.concurrent.ThreadFactory

线程池工厂(实现类)

java.util.concurrent.Executors.DefaultThreadFactory

java.util.concurrent.Executors.PrivilegedThreadFactory

(3)调度类线程体现

接口

java.util.concurrent.Executor

java.util.concurrent.ExecutorService

java.util.concurrent.ScheduledExecutorService

实现类

java.util.concurrent.ThreadPoolExecutor

实现类

java.util.concurrent.ScheduledThreadPoolExecutor

(4)其它

java.lang.SecurityManager

java.util.concurrent.ThreadPoolExecutor.Worker

2.使用Spring Boot注解配置线程池ExecutorService

(1)说明

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

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

(2)代码

@Configuration
public class ThreadPoolConfig {/*** 创建线程池*/@Bean("executorServiceHz")public ExecutorService executorService() {ExecutorService executorService = Executors.newFixedThreadPool(8, new ThreadFactory() {@Overridepublic Thread newThread(Runnable runnable) {return new Thread(runnable);}});return executorService;}
}

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

(1)说明

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

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

(2)代码

public class SportContestExecutor implements Runnable {private TaskDto taskDto;public SportContestExecutor(TaskDto taskDto) {this.taskDto = taskDto;}@Overridepublic void run() {String eventName = this.taskDto.getEventName();String content = this.taskDto.getContent();System.out.println("【线程: " + Thread.currentThread().getName() + ",在直播: " + eventName + content + "】");}
}

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

(1)说明

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

(2)代码

@Component("sportWorker02")
public class SportWorker02 {/*** 自动注入线程池*/@Autowiredprivate ExecutorService executorServiceHz;/*** 把线程任务提交到线程池*/public void holdGame() {//1.准备数据List<TaskDto> groupStage = new ArrayList<>();for (int i = 0; i < 10; i++) {String no = "" + (i + 1);if (i < 9) {no = "0" + (i + 1);}TaskDto taskDto01 = TaskDto.builder().eventName("羽毛球球比赛").content("小组赛" + no).build();groupStage.add(taskDto01);}//2.线程任务提交到线程池for (TaskDto taskDto : groupStage) {executorServiceHz.execute(new SportContestExecutor(taskDto));}}
}

5.测试示例

(1)说明

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

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

(2)代码

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

(3)输出结果

【线程: Thread-5,在直播: 羽毛球球比赛小组赛02】
【线程: Thread-4,在直播: 羽毛球球比赛小组赛01】
【线程: Thread-6,在直播: 羽毛球球比赛小组赛03】
【线程: Thread-7,在直播: 羽毛球球比赛小组赛04】
【线程: Thread-8,在直播: 羽毛球球比赛小组赛05】
【线程: Thread-7,在直播: 羽毛球球比赛小组赛09】
【线程: Thread-5,在直播: 羽毛球球比赛小组赛10】
【线程: Thread-10,在直播: 羽毛球球比赛小组赛07】
【线程: Thread-9,在直播: 羽毛球球比赛小组赛06】
【线程: Thread-11,在直播: 羽毛球球比赛小组赛08】

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;
}

以上,感谢。

2023年9月14日

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/84051.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

常用与业务密切相关的prompt

可以在 Bard、Bing、Claude 2、ChatGPT和 Llama 2 上使用 定义您的业务目的和愿景。 提示&#xff1a;“我正在[插入行业]创业。我的重点是定义与我的受众产生共鸣的明确目标和愿景。你能指导我制定有意义的愿景声明吗&#xff1f;” 研究和分析您的目标市场。 提示&#x…

可视化图表组件之股票数据分析应用

股市是市场经济的必然产物&#xff0c;在一个国家的金融领域之中有着举足轻重的地位。在过去&#xff0c;人们对于市场走势的把握主要依赖于经验和直觉&#xff0c;往往容易受到主观因素的影响&#xff0c;导致决策上出现偏差。如今&#xff0c;通过数据可视化呈现&#xff0c;…

Puppeter与Electron的结合,使用Electron创建可视化界面

前言 上一篇文章&#xff1a;Puppeteer基础入门、常见应用、利用谷歌插件编写Puppeteer脚本&#xff0c;简单介绍了Puppeteer的基本使用&#xff0c;以及如何编写一个脚本。 但是呢脚本的运行需要在node环境里&#xff0c;开发人员可能没什么问题。但是如果你写的这个脚本要给…

java学习笔记------接口

接口&#xff1a;就是一种规则&#xff08;是对行为的抽象&#xff09; 接口的定义和使用&#xff1a; 接口用关键字interface来定义 public interface 接口名{}接口不能实例化接口和类之间是实现关系&#xff0c;通过implements关键字表示 public class 类名 …

Selenium 4.11 正式发布--再也不用手动更新chrome driver 了

Selenium 4.11.0 正式发布了&#xff0c;先来看一下主要特性。 Chrome DevTools支持的版本现在是&#xff1a;v113、v114和v115&#xff08;Firefox仍然对所有版本使用v85&#xff09; 通过Selenium Manager支持Chrome For Testing&#xff08;CfT&#xff09; Selenium Manag…

RabbitMQ —— 初窥门径

前言 RabbitMQ作为当下主流的消息中间件之一&#xff0c;无疑是我们Java后端开发技术成长路线的重要一环&#xff0c;在这篇文章中荔枝将会梳理入门RabbitMQ的知识&#xff0c;文章涉及RabbitMQ的基本概念及其环境配置&#xff0c;荔枝的RabbitMQ是在Docker上部署的&#xff0c…

《TCP/IP网络编程》阅读笔记--多线程服务器端的实现

目录 1--多线程的优点 2--进程和线程的差异 3--线程创建 4--线程使用 5--线程安全问题 6--互斥量 7--信号量 8--线程销毁 9--多线程并发聊天程序 9-1--服务器端 9-2--客户端 9-3--测试结果 1--多线程的优点 多进程服务器的缺点&#xff1a; ① 创建进程的过程会带来…

Ubuntu 20.04中docker-compose部署Nightingale

lsb_release -r可以看到操作系统版本是20.04&#xff0c;uname -r可以看到内核版本是5.5.19。 sudo apt install -y docker-compose安装docker-compose。 完成之后如下图&#xff1a; cd /opt/n9e/docker/进入到/opt/n9e/docker/里边。 docker-compose up -d进行部署。 …

【LeetCode-中等题】150. 逆波兰表达式求值

文章目录 题目方法一&#xff1a;栈 题目 方法一&#xff1a;栈 class Solution {public int evalRPN(String[] tokens) {Deque<Integer> deque new LinkedList<>();String rpn "-*/";//符号集 用来判断扫描的是否为运算符int sum 0;for(int i 0 ; i…

华为云云耀云服务器L实例评测|centos7.9在线使用cloudShell下载rpm解压包安装mysql并开启远程访问

文章目录 ⭐前言⭐使用华为cloudShell连接远程服务器&#x1f496; 进入华为云耀服务器控制台&#x1f496; 选择cloudShell ⭐安装mysql压缩包&#x1f496; wget下载&#x1f496; tar解压&#x1f496; 安装步骤&#x1f496; 初始化数据库&#x1f496; 修改密码&#x1f4…

【zlm】 webrtc源码讲解

目录 前端WEB 服务器收到请求 服务端的处理 播放 拉流 参考文章 前端WEB 服务器收到请求 POST /index/api/webrtc?applive&streamtest&typeplay HTTP/1.1 HttpSession::onRecvHeaderHttpSession::Handle_Req_POSTHttpSession::Handle_Req_POSTif (totalConte…

科技评估分类

声明 本文是学习GB-T 42776-2023 科技评估分类. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本文件确立了科技评估的分类原则&#xff0c;描述了分类方法&#xff0c;规定了编码方法、分类与代码。 本文件适用于科技评估的规划、设计、委…

Ganache本地测试网+cpolar内网穿透实现公网访问内网

文章目录 前言1. 本地环境服务搭建2. 局域网测试访问3. 内网穿透3.1 ubuntu本地安装cpolar内网穿透3.2 创建隧道3.3 测试公网访问 4. 配置固定二级子域名4.1 保留一个二级子域名4.2 配置二级子域名4.3 测试访问公网固定二级子域名 前言 网&#xff1a;我们通常说的是互联网&am…

计算机毕设 大数据上海租房数据爬取与分析可视化 -python 数据分析 可视化

# 1 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通…

Linux内核顶层Makefile的make xxx_defconfig过程分析三

一. Linux内核的配置工作 本文具体分析 配置 Linux内核源码时&#xff0c;顶层 Makefile实际做的事。具体分析 "make xxx_defconfig"配置Linux内核源码时&#xff0c;顶层 Makefile做了什么。 本文续上一篇文章&#xff0c;地址如下&#xff1a; Linux内核顶层Mak…

error:03000086:digital envelope routines::initialization error问题解决

目录 问题描述&#xff1a;error:03000086:digital envelope routines::initialization error 问题原因&#xff1a;nodejs V17 版本发布了 OpenSSL3.0 对算法和秘钥大小增加了更为严格的限制&#xff0c;nodeJs v17 之前版本没影响&#xff0c;但 V17 和之后版本会出现这个错…

tauri vue vite elemrntui

tauri vue vite rust 根据 https://www.rust-lang.org/tools/install&#xff0c;安装 rust。如果是 windows 会跳出 vs 工具的安装器&#xff0c;会自动勾选要安装的&#xff0c;直接点安装即可 执行 cargo --version 检查安装是否完成&#xff0c;可以使用 cargo 创建一个…

短视频矩阵系统源代码开发搭建分享--代码开源SaaS

一、什么是短视频矩阵系统&#xff1f; 短视频矩阵系统是专门为企业号商家、普通号商家提供帐号运营从流量 到转化成交的一站式服务方案&#xff0c;具体包含&#xff1a;点赞关注评论主动私信 &#xff0c;评论区回复&#xff0c;自动潜客户挖掘&#xff0c;矩阵号营销&#x…

Codeforces Round 896 (Div. 1) C. Travel Plan(树形dp+组合数学)

题目 有一棵n(1<n<1e18)个点的树&#xff0c; 点i连着2*i和2*i1两个点&#xff0c;构成一棵完全二叉树 对于每个点i&#xff0c;记其值为a[i]&#xff0c;a[i]可以取[1,m](1<m<1e5)的整数 记i到j的简单路径上的最大值为s[i][j]&#xff0c; 则一棵权值确定的树…

邮件数据安全案例 | 有一种遇见,叫相见恨晚

Mr.赵回忆和联通相遇的时刻&#xff0c;他说&#xff0c;用一句诗来形容恰如其分&#xff0c;“众里寻他千百度&#xff0c;蓦然回首&#xff0c;那人却在&#xff0c;灯火阑珊处” 。 中国联合网络通信集团有限公司在国内31个省&#xff08;自治区、直辖市&#xff09;和境外…