当前位置: 首页 > news >正文

ThreadPool-线程池使用及原理

1. 线程池使用方式

示例代码:

// 一池N线程
Executors.newFixedThreadPool(int)
// 一个任务一个任务执行,一池一线程
Executors.newSingleThreadExecutorO
// 线程池根据需求创建线程,可扩容,遇强则强
Executors.newCachedThreadPool()
// 自定义线程池方式
new ThreadPoolExecutor(...)

注:一般在工作中都是根据业务场景进行自定义线程池,进行使用;
自定义线程池方法;详见后面章节:自定义线程池

2. 线程池底层工作原理

a. 线程池参数:

线程池,具有多个参数:具有各自的含义:

七参数:

  • corePoolSize:核心线程数,一直保持活跃状态的线程
  • maximumPoolSize:最大线程数,线程池能容纳的最大线程数量
  • keepAliveTime:空闲线程存活时间,非核心线程的空闲存活时间
  • unit:存活的时间单位,非核心线程的空闲存活时间单位
  • workQueue:存放未执行任务的队列
  • threadFactory:线程工厂,创建线程的工厂类
  • handler:拒绝策略,队列满了和达到最大线程数后的拒绝策略

如图:
在这里插入图片描述

b. 线程池的拒绝策略

AbortPolicy:默认,直接抛出RejectedExcutionException异常,阻止系统正常运行
CallerRunsPolicy:该策略既不会抛弃任务,也不会抛出异常,而是将某些任务回退到调用者
DiscardPolicy:直接丢弃任务,不予任何处理也不抛出异常,如果允许任务丢失,这是一种好方案
DiscardOldestPolicy:抛弃队列中等待最久的任务,然后把当前任务加入队列中尝试再次提交当前任务

c. 线程池底层工作原理

  1. 在创建了线程池后,如果设置了核心线程数(corePoolSize),则线程池中的线程数会先创建相应数量的核心线程。如果没有任务到达,这些核心线程会保持活动状态。

  2. 当调用execute()方法添加一个请求任务时,线程池会根据以下判断来决定任务的执行方式:

    • 如果正在运行的线程数量小于核心线程数(corePoolSize),则会立即使用核心线程来执行任务。
    • 如果正在运行的线程数量大于或等于核心线程数,但任务队列未满,则任务会被放入队列中等待执行。
    • 如果队列已满且正在运行的线程数量小于最大线程数(maximumPoolSize),则会创建非核心线程来执行任务。
      • 这里需要注意,是先执行新的任务,队列里的任务不会执行,详见:5. 注意事项
    • 如果队列已满且正在运行的线程数量已达到最大线程数,且拒绝策略允许,那么线程池会启动拒绝策略来处理新任务。
  3. 当一个线程完成任务时,它会从队列中取下一个任务来执行,或者在没有任务的情况下进入等待状态。

  4. 当一个线程空闲时间超过设定的keepAliveTime时,线程池会根据以下判断来决定线程的命运:

    • 如果当前运行的线程数大于核心线程数(corePoolSize),则空闲线程会被终止。
    • 线程池的所有任务完成后,它最终会收缩到核心线程数的大小。
  5. 注意事项:

    在Java中java.util.concurrent.ThreadPoolExecutor线程池的默认行为是,当任务队列已满且再来一个新任务时,创建的新线程会被用来执行新来的任务而不是队列里已有的任务。

  6. 线程工作原理示意图:

    • 在这里插入图片描述

3. 自定义线程池

a. 介绍:

前面提到过,一般在工作中都是根据业务场景进行自定义线程池;西面是阿里巴巴开发手册的说明;
在这里插入图片描述

b. 实现:

实现代码如下:

import org.jetbrains.annotations.NotNull;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.concurrent.*;/*** @author xxx* @version 1.0* @date xxx*/@Configuration
public class ThreadPoolExecutorConfig {@Beanpublic ThreadPoolExecutor threadPoolExecutor() {// 创建自定义线程池int corePoolSize = 2; // 核心线程数int maxPoolSize = 4; // 最大线程数long keepAliveTime = 10; // 线程空闲时间TimeUnit unit = TimeUnit.SECONDS; // 时间单位BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(10); // 任务队列ThreadFactory threadFactory = Executors.defaultThreadFactory(); // 线程工厂RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy(); // 拒绝策略// 创建ThreadPoolExecutor对象ThreadPoolExecutor threadPool = new ThreadPoolExecutor(corePoolSize,maxPoolSize,keepAliveTime,unit,workQueue,threadFactory,handler);return threadPool;}
}

4. 线程池参数的选择原则

仅供参考:具体的线程池参数,需要根据业务场景,进行合理的测试选择

一般原则:

在使用java.util.concurrent.ThreadPoolExecutor自定义线程池时,参数的设置需要根据具体的业务场景和需求进行调整。以下是一些常用的业务场景和设置原则:

  • 短时任务场景:
    corePoolSize (n+1):可以设置较小的值,例如CPU核心数加1。
    maximumPoolSize (2n):根据系统负载情况和任务的短时性来设置。通常可以设置为核心线程数的两倍或者根据系统资源进行调整。
    workQueue:可以选择容量较小的队列,例如SynchronousQueue,以避免任务积压。

  • 长时任务场景:
    corePoolSize:可以设置为一个相对较大的值,以确保有足够的线程处理任务。
    maximumPoolSize:根据系统负载和任务的长时性来设置。如果长时任务较多,可以将最大线程数设置得较大一些。
    keepAliveTime 和 TimeUnit:根据任务的处理时长和系统的响应时间来设置空闲线程的存活时间。

  • I/O密集型任务场景:
    corePoolSize(2n):可以设置为较大的值,以充分利用系统资源,加速I/O操作。
    maximumPoolSize:根据系统负载和I/O操作的并发数来设置,可以设置得比较大以应对高并发的情况。
    workQueue:可以选择一个适当大小的队列,以充分缓冲I/O任务,但不至于占用过多内存。

  • CPU密集型任务场景:
    corePoolSize:可以根据CPU核心数设置,以充分利用系统的多核处理能力。
    maximumPoolSize:可以设置得比较大,以应对突发的CPU密集型任务,但不要超过系统负载的承受范围。
    workQueue:选择一个合适大小的队列来缓冲任务,避免因任务积压导致性能下降。

设置原则:

要根据具体的业务需求和系统特点来选择参数。
要根据实际情况进行监控和调优,以确保线程池能够有效地处理任务并保持系统的稳定性和性能。
要平衡资源的利用和系统的响应能力,避免设置过大或过小的参数,导致资源浪费或性能问题。

相关文章:

ThreadPool-线程池使用及原理

1. 线程池使用方式 示例代码&#xff1a; // 一池N线程 Executors.newFixedThreadPool(int) // 一个任务一个任务执行&#xff0c;一池一线程 Executors.newSingleThreadExecutorO // 线程池根据需求创建线程&#xff0c;可扩容&#xff0c;遇强则强 Executors.newCachedThre…...

高性能服务系列【十一】主题匹配

主题匹配核心算法就是字符串匹配&#xff0c;在字符串匹配基础上&#xff0c;会加入分段匹配需求&#xff0c;类似URL的点分式字符串。这个算法在几个场景中十分普遍。 1、应用层的路由寻址。比如反向代理中&#xff0c;根据请求中的URL&#xff0c;转发到对应的后台服务。 2…...

Vue 2 组件发布到 npm 的常见问题解决

按照 Vue 2 组件打包并发布到 npm 的方法配置项目后&#xff0c;项目在实际开发过程中&#xff0c;随着代码写法的多样性增加而遇到的各种打包问题&#xff0c;本文将予以逐一解决&#xff1a; 本文目录 同时导出多个组件 样式表 import 问题解决 Json 文件 import 问题解决…...

p2p原理

p2p原理 P2P (Peer-to-Peer) 是一种分布式计算和网络架构模型&#xff0c;它允许对等节点之间直接通信和共享资源&#xff0c;而无需通过集中的服务器。P2P 原理的核心概念是平等性&#xff08;peer equality&#xff09;&#xff0c;即所有节点在网络中都具有相同的功能和能力…...

从供方协议管理到外部供方管理

从GJB 5000A的供方协议管理到GJB 5000B的外部供方管理&#xff0c;军用软件的研制对承接单位有了更高的标准和要求&#xff0c;也对外部供方管理有了更改的要求&#xff0c;让我们看看具体的变化吧&#xff01; 供方协议管理的目的&#xff1a; 管理供方产品的获取工作。 外部…...

微服务demo(四)nacosfeigngateway

一、gateway使用&#xff1a; 1、集成方法 1.1、pom依赖&#xff1a; 建议&#xff1a;gateway模块的pom不要去继承父工程的pom&#xff0c;父工程的pom依赖太多&#xff0c;极大可能会导致运行报错&#xff0c;新建gateway子工程后&#xff0c;pom父类就采用默认的spring-b…...

2D与动画

2D转换 1.移动 translate 1. 语法 transform: translate(x,y); 或者分开写 transform: translateX(n); transform: translateY(n); 2.重点 定义 2D 转换中的移动&#xff0c;沿着 X 和 Y 轴移动元素 translate最大的优点&#xff1a;不会影响到其他元素的位置 translat…...

Maven:构建现代化软件项目的强大工具

在软件开发的世界中&#xff0c;Maven 是一个备受欢迎的构建工具。它提供了一种标准化、自动化的方式来管理项目的依赖、构建过程和部署。本文将深入探讨 Maven 的各个方面&#xff0c;帮助您更好地理解和使用这一强大的工具。 一、Maven 的简介 Maven 是一个基于项目…...

脏牛提权(靶机复现)

目录 一、脏牛漏洞概述 二、漏洞复现 1.nmap信息收集 1.1.查看当前IP地址 1.2.扫描当前网段,找出目标机器 1.3.快速扫描目标机全端口 三、访问收集到的资产 192.168.40.134:80 192.168.40.134:1898 四、msf攻击 1.查找对应exp 2.选择对应exp并配置相关设置 五、内…...

用html写一个贪吃蛇游戏

<!DOCTYPE html> <html> <head><title>贪吃蛇</title><meta charset"UTF-8"><meta name"keywords" content"贪吃蛇"><meta name"Description" content"这是一个初学者用来学习的小…...

Topaz Gigapixel AI for Mac 图像放大软件

Topaz Gigapixel AI for Mac是一款专为Mac用户设计的智能图像放大软件。它采用了人工智能技术&#xff0c;特别是深度学习算法&#xff0c;以提高图像的分辨率和质量&#xff0c;使得图像在放大后仍能保持清晰的细节。这款软件的特点在于其能够将低分辨率的图片放大至高分辨率&…...

uniapp先显示提示消息再返回上一页

一、描述 在有些业务场景中&#xff0c;需要先弹出提示后&#xff0c;再返回上一页。 二、思路 使用定时器&#xff0c;先弹出提示消息&#xff0c;然后开个定时器俩秒后再执行&#xff0c;返回上一页的操作&#xff0c;并且清除定时器。 三、实现 uni.showToast({title: …...

【爬虫开发】爬虫从0到1全知识md笔记第2篇:requests模块,知识点:【附代码文档】

爬虫开发从0到1全知识教程完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;爬虫课程概要&#xff0c;爬虫基础爬虫概述,,http协议复习。requests模块&#xff0c;requests模块1. requests模块介绍,2. response响应对象,3. requests模块发送请求,4. request…...

【算法刷题day11】Leetcode: 20. 有效的括号、 1047. 删除字符串中的所有相邻重复项、150. 逆波兰表达式求值

20. 有效的括号 文档链接&#xff1a;[代码随想录] 题目链接&#xff1a;20. 有效的括号 状态&#xff1a;ok 题目&#xff1a; 给定一个只包括 ‘(’&#xff0c;‘)’&#xff0c;‘{’&#xff0c;‘}’&#xff0c;‘[’&#xff0c;‘]’ 的字符串 s &#xff0c;判断字符…...

推荐算法策略需求-rank model优化

1.pred_oobe (base) [rusxx]$ pwd /home/disk2/data/xx/icode/baidu/oxygen/rus-pipeline/pipeline-migrate/UserBaseActiveStatPipeline/his_session (base) [rusxx]$ sh test.sh 2. user_skill_history_dict_expt2包含userid [workxx]$ vim /home/work/xx/du-rus/du_rus_o…...

hadoop 常用命令

hadoop 常用命令 hadoop fs -mkdir /test hadoop fs -put /opt/frank/tb_test03.txt /test/ hadoop fs -ls /test/ hadoop fs -cat /test/tb_test03.txt hadoop fs -rm /test/tb_test03.txt hadoop dfs 也能使用、但不推荐&#xff0c;执行会提示&#xff1a; DEPRECATED: Us…...

pdf在浏览器上无法正常加载的问题

一、背景 觉得很有意思给大家分享一下。事情是这样的&#xff0c;开发给我反馈说&#xff0c;线上环境接口请求展示pdf异常&#xff0c;此时碰巧我前不久正好在ingress前加了一层nginx&#xff0c;恰逢此时内心五谷杂陈&#xff0c;思路第一时间便放在了改动项。捣鼓了好久无果…...

实时语音识别(Python+HTML实战)

项目下载地址&#xff1a;FunASR 1 安装库文件 项目提示所需要下载的库文件&#xff1a;pip install -U funasr 和 pip install modelscope 运行过程中&#xff0c;我发现还需要下载以下库文件才能正常运行&#xff1a; 下载&#xff1a;pip install websockets&#xff0c;pi…...

x86_64 ubuntu22.04编译MetaRTC

metaRTC5.0 API https://github.com/metartc/metaRTC/wiki/metaRTC5.0-API Sample https://github.com/metartc/metaRTC/wiki/metaRTC5.0-API-Sample MetaRTC7.0编译 https://github.com/metartc/metaRTC/wiki/Here-we-come,-write-a-C-version-of-webRTC-that-runs-everywhere…...

FreeRTOS day1

1.总结keil5下载代码和编译代码需要注意的事项 需要与板子连通 配置完成后才点击下载 2.总结STM32Cubemx的使用方法和需要注意的事项 下载支持包 打开芯片配置界面 3.总结STM32Cubemx配置GPIO的方法...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

Rust 开发环境搭建

环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行&#xff1a; rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu ​ 2、Hello World fn main() { println…...

从面试角度回答Android中ContentProvider启动原理

Android中ContentProvider原理的面试角度解析&#xff0c;分为​​已启动​​和​​未启动​​两种场景&#xff1a; 一、ContentProvider已启动的情况 1. ​​核心流程​​ ​​触发条件​​&#xff1a;当其他组件&#xff08;如Activity、Service&#xff09;通过ContentR…...