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

谷粒微服务高级篇学习笔记整理---异步线程池

多线程回顾

多线程实现的4种方式


1. 继承 Thread

通过继承 Thread 类并重写 run() 方法实现多线程。

public class MyThread extends Thread {@Overridepublic void run() {System.out.println("线程运行: " + Thread.currentThread().getName());}
}// 使用
public static void main(String[] args) {MyThread thread = new MyThread();thread.start(); // 启动线程
}

特点

  • 缺点:Java 单继承的限制,无法再继承其他类。
  • 适用场景:简单任务,无需共享资源。

2. 实现 Runnable 接口

实现 Runnable 接口,将任务逻辑写在 run() 方法中。

public class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("线程运行: " + Thread.currentThread().getName());}
}// 使用
public static void main(String[] args) {Thread thread = new Thread(new MyRunnable());thread.start();
}

特点

  • 优点:避免单继承限制,适合资源共享(如多个线程处理同一任务)。
  • 推荐场景:大多数情况下优先使用。

3. 实现 Callable 接口 + Future

通过 Callable 允许返回结果和抛出异常,结合 FutureFutureTask 获取异步结果。

import java.util.concurrent.*;public class MyCallable implements Callable<String> {@Overridepublic String call() throws Exception {return "执行结果: " + Thread.currentThread().getName();}
}// 使用
public static void main(String[] args) throws Exception {ExecutorService executor = Executors.newSingleThreadExecutor();Future<String> future = executor.submit(new MyCallable());System.out.println(future.get()); // 阻塞获取结果executor.shutdown();
}

特点

  • 优点:支持返回值和异常处理。
  • 适用场景:需要获取线程执行结果的场景。

4. 使用线程池(Executor 框架)

通过 Executors 工具类创建线程池,统一管理线程资源。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadPoolDemo {public static void main(String[] args) {ExecutorService executor = Executors.newFixedThreadPool(3);for (int i = 0; i < 5; i++) {executor.execute(() -> {System.out.println("线程运行: " + Thread.currentThread().getName());});}executor.shutdown();}
}

特点

  • 优点:降低资源消耗,提高线程复用率,支持任务队列和拒绝策略。
  • 推荐场景:生产环境首选,高并发任务处理。

对比与建议
方式返回值异常处理灵活性资源消耗
继承 Thread不支持有限
实现 Runnable不支持有限
实现 Callable支持支持
线程池(Executor支持支持最高最低

建议

  • 优先选择 实现 Runnable/Callable 接口,避免继承局限性。
  • 生产环境务必使用 线程池,提升性能并确保稳定性。
  • 需要结果时使用 Callable + Future,简单任务用 Runnable

线程池ExecutorService的7大参数

线程池构造函数

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler
)
参数说明
1. 核心线程数(corePoolSize)
  • 作用:线程池中始终保持存活的线程数量(即使空闲)。
  • 特点
    • 默认情况下,核心线程在空闲时不会销毁(除非设置 allowCoreThreadTimeOut(true))。
2. 最大线程数(maximumPoolSize)
  • 作用:线程池允许创建的最大线程数(包括核心线程和非核心线程)。
  • 规则
    • 当任务队列已满且当前线程数小于最大线程数时,会创建新线程处理任务。
3. 线程存活时间(keepAliveTime + unit)
  • 作用:非核心线程空闲时的存活时间。unit为时间单位
  • 规则
    • 非核心线程在空闲时间超过 keepAliveTime 后会被销毁。
    • 如果 allowCoreThreadTimeOut(true),核心线程也会受此时间限制。
4. 任务队列(workQueue)
  • 作用:用于存放待执行任务的阻塞队列。
  • 常见队列类型
    • 无界队列:如 LinkedBlockingQueue(默认无界,可能导致 OOM)。
    • 有界队列:如 ArrayBlockingQueue(需指定容量)。
    • 同步移交队列:如 SynchronousQueue(不存储任务,直接移交线程)。
5. 线程工厂(threadFactory)
  • 作用:自定义线程的创建方式(如命名、优先级、是否为守护线程等)。
  • 默认实现Executors.defaultThreadFactory()
6. 拒绝策略(handler)
  • 作用:当任务队列已满且线程数达到最大时,如何处理新提交的任务。
  • 常见策略
    • AbortPolicy(默认):抛出 RejectedExecutionException异常,且不会静默丢弃任务
    • CallerRunsPolicy:由提交任务的线程直接执行任务。
    • DiscardPolicy:静默丢弃新任务。
    • DiscardOldestPolicy:丢弃队列中最旧的任务,尝试重新提交新任务。
运行流程
1. 线程池创建,准备好 core 数量的核心线程,准备接受任务2. 新的任务进来,用 core 准备好的空闲线程执行。(1)、core满了,就将再进来的任务放入阻塞队列中。空闲的 core 就会自己去阻塞队列获取任务执行(2)、阻塞队列满了,就直接开新线程执行,最大只能开到max指定的数量(3)、max都执行好了。Max-core 数量空闲的线程会在 keepAliveTime指定的时间后自动销毁。最终保持到 core 大小(4)、如果线程数开到了 max的数量,还有新任务进来,就会使用 reject 指定的拒绝策略进行处理3. 所有的线程创建都是由指定的 factory 创建的。
  1. 优先级顺序:核心线程 → 任务队列 → 非核心线程 → 拒绝策略。
  2. 非核心线程:仅在队列满时创建,空闲超时后销毁
  3. 队列选择
    • 无界队列:可能导致 OOM(如 LinkedBlockingQueue)。
    • 同步队列:适合高并发快速响应(如 SynchronousQueue)。

常见面试问题:

一个线程池中core 7; max 20; quue 50, 100个并发进来怎么分配:
7个会被立即执行,50个进入阻塞队列,再开13个线程进行执行,剩下的30个就使用拒绝策略

常见4种线程池

A、newCachedThreadPool

创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
core是0,所有都可回收

B、newFixedThreadPool

创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
固定大小,core=max;都不可回收

C、newScheduledThreadPool

创建一个定长线程池,支持定时及周期性任务执行。
定时任务的线程池

D、newSingleThreadExecutor

创建一个单线程化的线程池,它只会用唯一

相关文章:

谷粒微服务高级篇学习笔记整理---异步线程池

多线程回顾 多线程实现的4种方式 1. 继承 Thread 类 通过继承 Thread 类并重写 run() 方法实现多线程。 public class MyThread extends Thread {@Overridepublic void run() {System.out.println("线程运行: " + Thread.currentThread().getName());} }// 使用 p…...

清晰易懂的 Flutter 开发环境搭建教程

Flutter 是 Google 推出的跨平台应用开发框架&#xff0c;支持 iOS/Android/Web/桌面应用开发。本教程将手把手教你完成 Windows/macOS/Linux 环境下的 Flutter 安装与配置&#xff0c;从零到运行第一个应用&#xff0c;全程避坑指南&#xff01; 一、安装 Flutter SDK 1. 下载…...

图形界面设计理念

一、图形界面的组成 1、窗口 窗口约束了图形界面的边界&#xff0c;提供最小化、最大化、关闭的按钮。 2、菜单栏 一般在界面的上方&#xff0c;提供很多功能选项。 3、工具栏 一般是排成一列&#xff0c;每个图标代表一个功能。 工具栏是为了快速的调用经常使用的功能。 4、导…...

MySQL-- 函数(单行函数): 日期和时间函数

目录 1,获取日期、时间 2,日期与时间戳的转换 3,获取月份、星期、星期数、天数等函数 4,日期的操作函数 5,时间和秒钟转换的函数 6,计算日期和时间的函数 7,日期的格式化与解析 1,获取日期、时间 CURDATE() &#xff0c;CURRENT_DATE() 返回…...

DeepSeek真的超越了OpenAI吗?

DeepSeek 现在确实很有竞争力&#xff0c;但要说它完全超越了 OpenAI 还有点早&#xff0c;两者各有优势。 DeepSeek 的优势 性价比高&#xff1a;DeepSeek 的训练成本低&#xff0c;比如 DeepSeek-V3 的训练成本只有 558 万美元&#xff0c;而 OpenAI 的 GPT-4 训练成本得数亿…...

Node 22.11使用ts-node报错

最近开始学ts&#xff0c;发现使用ts-node直接运行ts代码的时候怎么都不成功&#xff0c;折腾了一番感觉是这个node版本太高还不支持&#xff0c; 于是我找了一个替代品tsx npm install tsx -g npx tsx your-file.ts -g代表全局安装&#xff0c;也可以开发环境安装&#xff0…...

LabVIEW中VISA Write 与 GPIB Write的差异

在使用 LabVIEW 与 GPIB 设备通讯时&#xff0c;VISA Write Function 和 GPIB Write Function 是两个常用的函数&#xff0c;它们既有区别又有联系。 一、概述 VISA&#xff08;Virtual Instrument Software Architecture&#xff09;是一种用于仪器编程的标准 I/O 软件库&…...

牛客练习题——素数(质数)

质数数量 改题目需要注意的是时间 如果进行多次判断就会超时&#xff0c;这时需要使用素数筛结合标志数组进行对所有数据范围内进行判断&#xff0c;而后再结合前缀和将结果存储到数组中&#xff0c;就可以在O(1)的时间复杂度求出素数个数。 #include<iostream>using nam…...

使用MQTTX软件连接阿里云

使用MQTTX软件连接阿里云 MQTTX软件阿里云配置MQTTX软件设置 MQTTX软件 阿里云配置 ESP8266连接阿里云这篇文章里有详细的创建过程&#xff0c;这里就不再重复了&#xff0c;需要的可以点击了解一下。 MQTTX软件设置 打开软件之后&#xff0c;首先点击添加进行创建。 在阿…...

qt实现功率谱和瀑布图

瀑布图 配置qcustomplot的例子网上有很多了&#xff0c;记录下通过qcustomplot实现的功率谱和瀑布图代码&#xff1a; void WaveDisplay::plotWaterfall(MCustomPlot* p_imag) {mCustomPlotLs p_imag;mCustomPlotLs->plotLayout()->clear(); // clear default axis rect…...

通过发音学英语单词:从音到形的学习方法

&#x1f4cc; 通过发音学英语单词&#xff1a;从音到形的学习方法 英语是一种 表音语言&#xff08;phonetic language&#xff09;&#xff0c;但不像拼音文字&#xff08;如汉语拼音、西班牙语等&#xff09;那么规则&#xff0c;而是 部分表音部分表意。这意味着我们可以通…...

WebUI问题总结

修改WebUI代码时遇到的一些问题以及解决办法 1. thttpd服务器环境的搭建 可参考《thttpd安装与启动流程》这一篇文章 其中遇到的问题有 thttpd版本问题&#xff1a;版本过旧会导致安装失败&#xff0c;尽量安装新版本thttpd的启动命令失败的话要加上sudo修改文件权限&#…...

23种设计模式-行为型模式-责任链

文章目录 简介问题解决代码核心改进点&#xff1a; 总结 简介 责任链是一种行为设计模式&#xff0c;允许你把请求沿着处理者链进行发送。收到请求后&#xff0c;每个处理者均可对请求进行处理&#xff0c;或将其传递给链上的下个处理者。 问题 假如你正在开发一个订单系统。…...

git commit Message 插件解释说明

- feat - 一项新功能 - fix - 一个错误修复 - docs - 仅文档更改 - style - 不影响代码含义的更改&#xff08;空白、格式化、缺少分号等&#xff09; - refactor - 既不修复错误也不添加功能的代码更改 - perf - 提高性能的代码更改 - build - 影响构建系统或外部依赖项…...

推荐系统(二十一):基于MaskNet的商品推荐CTR模型实现

MaskNet 是微博团队 2021 年提出的 CTR 预测模型,相关论文:《MaskNet: Introducing Feature-Wise Multiplication to CTR Ranking Models by Instance-Guided Mask》。MaskNet 通过掩码自注意力机制,在推荐系统中实现了高效且鲁棒的特征交互学习,特别适用于需处理长序列及噪…...

OpenCV 从入门到精通(day_04)

1. 绘制图像轮廓 1.1 什么是轮廓 轮廓是一系列相连的点组成的曲线&#xff0c;代表了物体的基本外形。相对于边缘&#xff0c;轮廓是连续的&#xff0c;边缘不一定连续&#xff0c;如下图所示。其实边缘主要是作为图像的特征使用&#xff0c;比如可以用边缘特征可以区分脸和手…...

多模态学习(八):2022 TPAMI——U2Fusion: A Unified Unsupervised Image Fusion Network

论文链接&#xff1a;https://ieeexplore.ieee.org/stamp/stamp.jsp?tp&arnumber9151265 目录 一.摘要 1.1 摘要翻译 1.2 摘要解析 二.Introduction 2.1 Introduciton翻译 2.2 Introduction 解析 三. related work 3.1 related work翻译 3.2 relate work解析 四…...

JavaEE-0403学习记录

通过前期准备后&#xff0c;项目已经能够成功运行&#xff1a; 1、在文件UserMapper.java中添加如下代码&#xff1a; List<User> selectUSerByIdDynamic(User user); 2、在文件UserMapper.xml中添加如下代码&#xff1a; <select id"selectUSerByIdDynamic&quo…...

图像处理:使用Numpy和OpenCV实现傅里叶和逆傅里叶变换

文章目录 1、什么是傅里叶变换及其基础理论 1.1 傅里叶变换 1.2 基础理论 2. Numpy 实现傅里叶和逆傅里叶变换 2.1 Numpy 实现傅里叶变换 2.2 实现逆傅里叶变换 2.3 高通滤波示例 3. OpenCV 实现傅里叶变换和逆傅里叶变换及低通滤波示例 3.1 OpenCV 实现傅里叶变换 3.2 实现逆傅…...

洛谷题单2-P5715 【深基3.例8】三位数排序-python-流程图重构

题目描述 给出三个整数 a , b , c ( 0 ≤ a , b , c ≤ 100 ) a,b,c(0\le a,b,c \le 100) a,b,c(0≤a,b,c≤100)&#xff0c;要求把这三位整数从小到大排序。 输入格式 输入三个整数 a , b , c a,b,c a,b,c&#xff0c;以空格隔开。 输出格式 输出一行&#xff0c;三个整…...

RNN模型与NLP应用——(7/9)机器翻译与Seq2Seq模型

声明&#xff1a; 本文基于哔站博主【Shusenwang】的视频课程【RNN模型及NLP应用】&#xff0c;结合自身的理解所作&#xff0c;旨在帮助大家了解学习NLP自然语言处理基础知识。配合着视频课程学习效果更佳。 材料来源&#xff1a;【Shusenwang】的视频课程【RNN模型及NLP应用…...

使用YoloV5和Mediapipe实现——上课玩手机检测(附完整源码)

目录 效果展示 应用场景举例 1. 课堂或考试监控&#xff08;看到这个学生党还会爱我吗&#xff09; 2. 驾驶安全监控&#xff08;防止开车玩手机&#xff09; 3. 企业办公管理&#xff08;防止工作时间玩手机&#xff09; 4. 监狱、戒毒所、特殊场所安保 5. 家长监管&am…...

XT-912在热交换站的应用

热网监控需求 随着国民经济的不断进步和人民生活水平日益提高&#xff0c;社会对环境的要求越来越高。近年来国家大力提倡城镇集中供热&#xff0c;改变原来各单位、各片区自己供热、单独建立锅炉房给城市带来的污染&#xff0c;由城市外围的一个或者多个热源厂提供热源&#…...

语文常识推翻百年“R完备、封闭”论

​语文常识推翻百年“R完备、封闭”论 黄小宁 李四光&#xff1a;迷信权威等于扼杀智慧。语文常识表明从西方传进来的数学存在重大错误&#xff1a;将无穷多各异数轴误为同一轴。 复平面z各点z的对应点zk的全体是zk平面。z面平移变换为zk&#xff08;k是非1正实常数&#xf…...

解决backtrader框架下日志ValueError: I/O operation on closed file.报错(jupyternotebook)

解决办法&#xff1a; 禁用 IPython 内核的日志重定向 在 IPython 环境下&#xff0c;内核可能会对日志进行重定向&#xff0c;从而引发问题。你可以尝试在运行代码之前禁用 IPython 的日志重定向&#xff1a; import logging# 禁用IPython内核的日志重定向 logging.getLogg…...

基于Docker容器部署DeepSeek-R1-Distill-Qwen-7B

首先打开魔搭社区&#xff0c;然后搜索DeepSeek-R1-Distill-Qwen-7B&#xff0c;进入详情页 官方推荐使用vllm来启动&#xff0c;但是手动搭建vllm环境容易出各种问题&#xff0c;我们这里直接找一个vllm的Docker镜像 一、拉取镜像 docker pull vllm/vllm-openai 如果拉取不…...

UART双向通信实现(序列机)

前言 UART&#xff08;通用异步收发传输器&#xff09;是一种串行通信协议&#xff0c;用于在电子设备之间进行数据传输。RS232是UART协议的一种常见实现标准&#xff0c;广泛应用于计算机和外围设备之间的通信。它定义了串行数据的传输格式和电气特性&#xff0c;以确…...

CentOS 7 全流程部署Magic-PDF数据清洗工具(附GPU加速方案)

CentOS 7 全流程部署Magic-PDF数据清洗工具&#xff08;附GPU加速方案&#xff09; 一、环境准备与方案选型 1.1 硬件要求 配置项最低要求推荐配置CPU4核8核内存8GB16GB存储50GBSSD/NVMeGPU可选NVIDIA T4 1.2 系统环境检查 # 查看系统版本 cat /etc/redhat-release# 检查G…...

2.1 路径问题专题:LeetCode 62. 不同路径

动态规划解决LeetCode 62题&#xff1a;不同路径问题 1. 题目链接 LeetCode 62. 不同路径 2. 题目描述 一个机器人位于一个 m x n 网格的左上角&#xff08;起点标记为“Start”&#xff09;。机器人每次只能向右或向下移动一步。机器人试图达到网格的右下角&#xff08;标…...

“*(单星号)”和“**(双星号)”在Python中的灵活运用

在Python中&#xff0c;*和**是两个重要的运算符&#xff0c;它们具有不同的用途。 一、*&#xff08;单星号&#xff09; 1、*&#xff08;单星号&#xff09;作为乘法运算符 2、*&#xff08;单星号&#xff09; 用于解包序列或可迭代对象 ‌ 用于解包序列或可迭代对象&…...