首页 > 其他分享 >学习【线程池】原理知识这一篇就够了

学习【线程池】原理知识这一篇就够了

时间:2024-07-28 10:24:12浏览次数:17  
标签:一篇 队列 Worker 就够 任务 线程 执行 动态化

线程池

线程池原理知识

1. 线程池基础

线程池是什么

线程池概念:

  • 是⼀种基于池化思想管理线程的工具。

线程池好处:

  • 如果没有线程池,线程过多会带来额外的开销,例如:创建销毁线程的开销、调度线程的开销
  • 线程池负责维护多个线程,一方面避免了处理任务时创建销毁线程开销的代价,另一方面避免了线程数量膨胀导致的过分调度问题。
  • 线程池好处包括:
    1. 降低资源消耗:通过池化技术重复利用已创建的线程,降低线程创建和销毁造成的损耗。
    2. 提高响应速度:任务到达时,无需等待线程创建即可立即执行。
    3. 提高线程的可管理性: 线程是稀缺资源,如果无限制创建,不仅会消耗系统资源,还会因为线程的不合理分布导致资源调度失衡,降低系统的稳定性。使用线程池可以进行统一的分配、监控。

线程池解决了什么问题

线程池解决的核心问题就是资源管理问题。在并发环境下,系统不能够确定在任意时刻,有多少任务需要执行,有多少资源需要投入。这种不确定性会降低系统的稳定性。

为了解决资源分配问题,线程池采用了池化的思想。就是将资源统一在一起管理的思想。

2. 线程池核心设计与实现

总体设计

在这里插入图片描述

ThreadPoolExecutor一方面维护自身的生命周期,另一方面管理线程和任务,使两者良好的结合从而执行并行任务。

生命周期管理

ThreadPoolExecutor的运行状态有5种,分别为

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

任务执行机制

1. 任务调度

任务调度是线程池的主要入口,当用户提交了⼀个任务,接下来这个任务将如何执行都是由这个阶段决定的。

任务调度的执行过程:

  1. 首先检测线程池运行状态,如果不是RUNNING,则直接拒绝,线程池要保证在RUNNING的状态下执行任务。
  2. 如果workerCount < corePoolSize,则创建并启动⼀个线程来执行新提交的任务。
  3. 如果workerCount >= corePoolSize,且线程池内的阻塞队列未满,则将任务添加到该阻塞队列中。
  4. 如果workerCount >= corePoolSize && workerCount < maximumPoolSize,且线程池内的阻塞队列已满,则创建并启动⼀个线程来执行新提交的任务。
  5. 如果workerCount >= maximumPoolSize,并且线程池内的阻塞队列已满,则根据拒绝策略来处理该任务,默认的处理方式是直接抛异常。

在这里插入图片描述

2. 任务缓冲

线程池中是以生产者消费者模式,通过一个阻塞队列来实现的。阻塞队列缓存任务,工作线程从阻塞队列中获取任务。

在这里插入图片描述

3. 任务申请

任务申请有2种:

  1. 任务直接由新创建的线程执行,无需调用 getTask() 获取任务。
  2. 任务先被放到任务队列,然后再由空闲线程申请,此时线程需要调用 getTask() 申请任务。

getTask() 申请任务流程图

在这里插入图片描述

4. 任务拒绝

当线程池的任务缓存队列已满,并且线程池中的线程数目达到 maximumPoolSize 时,就需要拒绝掉该任务,采取任务拒绝策略,保护线程池。

拒绝策略是⼀个接口,其设计如下:

public interface RejectedExecutionHandler {
 	void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
}

⽤户可以通过实现这个接口去定制拒绝策略,也可以选择JDK提供的四种已有拒绝策略,其特点如下:

在这里插入图片描述

Worker线程管理

Worker线程

Worker线程增加

Worker线程回收

Worker线程执行任务

3. 线程池在业务中的实践

业务背景

场景一:快速响应用户请求

用户的发起的实时请求,往往需要多个调用,之后要将所有的数据聚合起来返回给用户。

为了追求响应时间,可以使用线程池将调用封装成任务并行的执行,缩短总体响应时间

在这里插入图片描述

场景二:快速处理批量任务

这种场景需要执行大量的任务,并不要求瞬时完成,而是关注在单位时间内,尽可能的处理更多的任务。

可以使用线程池,并行执行任务,提高吞吐量。

实际问题及方案思考

4. 动态化线程池设计方案

动态化线程池:

  • 将线程池的参数从代码中迁移到分布式配置中心上,实现线程池参数可动态配置和即时生效,线程池参数动态化前后的参数修改流程对比如下:

在这里插入图片描述

动态化线程池整体设计:

在这里插入图片描述

动态修改配置

线程池构造参数有8个,但是最核心的是3个:corePoolSizemaximumPoolSizeworkQueue

所以线程池只需要提供这三个关键参数的配置即可。

线程池信息监控

动态化线程池考虑了多个维度的监控。如:线程池活跃度、任务的执行Transaction(频率、耗时)、Reject异常、线程池内部统计信息等。

这些监控信息既能从多个维度分析线程池的使用情况,又能在出现问题第一时间通知到用户,从而避免故障或加速故障恢复。

线程池告警通知

可以从两方面来看线程池的过载判定条件。

  1. 发生了 Reject 异常
  2. 任务队列中的等待任务超过指定的阈值、

以上两种情况发生了都会触发告警,告警信息会通过邮件发送给负责人。

参考文章:

Java线程池实现原理及其在美团业务中的实践

标签:一篇,队列,Worker,就够,任务,线程,执行,动态化
From: https://blog.csdn.net/weixin_44147535/article/details/135191215

相关文章

  • 旧文一篇《然并卵》
    你在论坛上和人针砭时弊,痛斥腐败,向往民主,然而这些并没有什么卵用,你无力改变什么。你和人交流新上市那部电影好看,哪部电影该得烂番茄奖,然而这些并没有什么卵用,每个人都有他喜欢和不喜欢的东西。为了喜欢的球队,球员,比赛和人争的面红耳赤,然而这些并没有什么卵用,他们打他们的比赛......
  • JavaEE 初阶(8)——多线程6之线程安全下-->volatile
    之前,我们在 JavaEE初阶(6) 这篇文章中,谈到过引起线程不安全的原因,初步了解了 “可见性” “Java内存模型” “指令重排序”,本章讲解volatile会涉及到这三个知识点,详细内容可以参考  JavaEE初阶(6) 这篇文章。目录一. 引入二.volatile关键字 a.保证“可......
  • JavaEE 初阶(7)——多线程5之线程安全中 -->“死锁”
    目录一.什么是“死锁”二.产生死锁的场景  场景1:一个线程连续加锁 场景2:两个线程两把锁场景3:N个线程M把锁 三.产生死锁的四个必要条件(缺一不可)四. Java标准库中的线程安全类一.什么是“死锁”并非是synchronized就一定线程安全,还要看代码具体咋写。到底......
  • JavaEE 初阶(9)——多线程7之 wait 和 notify
    目录一.监视器锁与监视器二.wait()  三.notify()和notifyAll()3.1notify() 3.2notifyAll()3.3wait等待 和sleep休眠的对比(面试题)wait(等待)/notify(通知)由于线程在操作系统上是“随机调度,抢占式执行”的,因此线程之间执行的先后顺序难以预知。但是......
  • 小白的第一篇blog
    Markdown学习1.标题要写标题可用#加空格,再下字,然后再用回车键。2.字体1.粗体打法:在文字两侧加两个*如:helloworld!2.斜体打法:在文字两侧加一个*如:helloworld!3.既要斜体又要粗体打法:在文字两侧加三个*如helloworld!4.划线打法:在文字两侧加两个~~如:helloworld!3.引......
  • 多线程实现阻塞队列
    今天面试被问到了,多线程实现阻塞队列,记录一下。1importjava.util.LinkedList;2importjava.util.Queue;3importjava.util.concurrent.locks.Condition;4importjava.util.concurrent.locks.ReentrantLock;56publicclassFixedSizeBlockingQueue<T>{7......
  • 收藏多年的线程安全问题大全笔记(1),笔记一生一起走,那些日子不再有
    本篇会加入个人的所谓鱼式疯言❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言而是理解过并总结出来通俗易懂的大白话,小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的.......
  • RT-Thread多线程
    RT-Thread启动流程分析线程的状态初始状态:线程刚开始创建,还没开始运行时就处于,初始状态。就绪状态:在就绪状态下,线程按照优先级排队,等待被执行。运行状态:线程正在运行,在单核系统中,只有rt_thread_self()函数返回的线程处于运行状态,但多核系统下,运行的线程不止一个。......
  • CTF入门,看这一篇文章就够了
    CTF从入门到提升一、Web基础HTTP请求包HTTP请求方法定义了HTTP请求时所要告诉服务器执行的动作。常见的HTTP请求方法有以下几种:•GET:通常用于直接获取服务器上的资源•POST:一般用于向服务器发送数据,常用于更新资源信息•PUT:一般用于新增一个数据记录•PATCH:一般用于......
  • 本地部署大模型?看这篇就够了,Ollama 部署和实战
    写在前面前几篇,分享的都是如何白嫖国内外各大厂商的免费大模型服务~有小伙伴问,如果我想在本地搞个大模型玩玩,有什么解决方案?Ollama,它来了,专为在本地机器便捷部署和运行大模型而设计。也许是目前最便捷的大模型部署和运行工具,配合OpenWebUI,人人都可以拥有大模型自由。......