详解线程池的作用和实际应用以及拒绝策略

news2024/11/16 3:44:29

目录

线程池的作用?

线程池的意义:

线程池的参数

​编辑

 线程池任务执行的顺序

线程池拒绝策略

四种策略

 应用场景分析

AbortPolicy

DiscardPolicy

DiscardOldestPolicy

CallerRunsPolicy


线程池的作用?

优化系统架构通常包括在时间和空间之间进行权衡。对于线程池的创建,采用线程池预先创建并维护一定数量的线程,以空间换取时间的方式,可以有效减少每次任务执行时创建线程所带来的开销。

通过预先创建一定数量的线程并将其放入线程池中,可以避免在任务到来时动态创建线程的开销。相反,任务可以直接从线程池中获取可用的线程并执行,这样可以显著降低任务处理的延迟时间。这种池化思想利用了空间来存储预先创建的线程,以提高整体系统性能。

通过将线程池用作线程的缓存,可以避免重复创建和销毁线程的开销,提高系统的吞吐量和响应性能。此外,线程池还可以根据系统负载的变化动态调整线程的数量,以提供更好的性能和资源利用率。

因此,通过采用线程池来预先创建和维护线程的方式,可以在一定程度上优化系统架构,通过牺牲一部分空间,来换取更高的执行效率和响应能力。

线程池的意义:

  1. 降低资源的消耗:线程的创建和销毁需要消耗一定的计算机资源,包括内存和CPU时间。通过线程池,可以避免重复地创建和销毁线程,提高资源的利用率。

  2. 提高响应的速度:线程池中的线程已经预先创建并准备好执行任务。当任务到达时,可以直接分配一个可用的线程来处理,而不需要等待线程创建。这样可以大大降低任务的响应时间,提供更快的服务。

  3. 方便管理:线程池提供了对线程的统一管理和调度。通过线程池的接口,可以方便地控制线程的数量、设置线程的优先级、监测线程的执行状态等。此外,线程池中的线程通常有一个名称,方便在日志或调试信息中进行追踪和定位,从而方便排查问题和进行故障诊断。

线程池的参数

最小线程数:项目启动的时候,初始化的线程数 1

核心线程数:当线程池的线程都忙碌时,再进来新任务时,由最小线程数扩容到核心线程数 4

最大线程数 8:当核心线程数满了,当队列也满了,再来新任务,就会创建新线程来执行这个新任务,直到线程数达到最大线程数

队列大小 1000:当线程数达到核心线程数,再进来的任务就会进入到队列。

线程同一时刻只能做一件事,如下图需要等待上一步完成才能进行下一步

现在采用多线程,就可以同一时刻去进行多个任务,等最慢的线程结束就认为当前任务完成

 线程池任务执行的顺序

 最开始线程池中会有空线程在等待任务,当有任务出现就会安排线程去执行,如果没有空线程就会创建新的线程,当线程达到了核心线程数并且没有线程是空闲的 就开始往队列里面添加线程,如果队列中线程也达到饱和状态则继续创建新线程,直到线程数量达到最大线程数,开始进行拒绝策略

需要注意的是当任务队列已满且线程池的最大线程数尚未达到上限时,此时有新的线程出现,新线程将会被创建,并且会执行这个新的任务,而不是从队列中取出任务。

具体来说,当任务队列已满时,线程池会创建新的线程,并将新的任务分配给这个新线程来执行。这样可以避免将新任务放入已满的队列中,而是直接创建线程来处理新任务。

当线程池的核心线程数、任务队列容量和最大线程数都达到上限时,才会根据拒绝策略来处理新的任务

线程池拒绝策略

四种策略

ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务
ThreadPoolExecutor.CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务

线程池的默认拒绝策略为AbortPolicy,即丢弃任务并抛出RejectedExecutionException异常。

通过代码来验证这一点,现有如下代码:

public class ThreadPoolTest {
    public static void main(String[] args) {
        BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(60);
        ThreadFactory factory = r -> new Thread(r, "test-thread-pool");
        ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 5,
                0L, TimeUnit.SECONDS, queue, factory);
        while (true) {
            executor.submit(() -> {
                try {
                   System.out.println(queue.size());
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
    }
}

 设置了最大队列数为60,没有设置拒绝策略,运行代码则会抛出RejectedExecutionException异常

 应用场景分析

AbortPolicy

ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。

A handler for rejected tasks that throws a {@code RejectedExecutionException}.

这是线程池默认的拒绝策略,在任务不能再提交的时候,抛出异常,及时反馈程序运行状态。如果是比较关键的业务,推荐使用此拒绝策略,这样子在系统不能承载更大的并发量的时候,能够及时的通过异常发现。

DiscardPolicy

ThreadPoolExecutor.DiscardPolicy:丢弃任务,但是不抛出异常。如果线程队列已满,则后续提交的任务都会被丢弃,且是静默丢弃。

A handler for rejected tasks that silently discards therejected task.

使用此策略,可能会使我们无法发现系统的异常状态。建议是一些无关紧要的业务采用此策略。

DiscardOldestPolicy

ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务。

A handler for rejected tasks that discards the oldest unhandled request and then retries {@code execute}, unless the executor is shut down, in which case the task is discarded.

此拒绝策略,是一种喜新厌旧的拒绝策略。是否要采用此种拒绝策略,还得根据实际业务是否允许丢弃老任务来认真衡量。

CallerRunsPolicy

ThreadPoolExecutor.CallerRunsPolicy:由主线程处理该任务

A handler for rejected tasks that runs the rejected task directly in the calling thread of the {@code execute} method, unless the executor has been shut down, in which case the task is discarded.
import java.util.concurrent.*;

public class Test {
    public static void main(String[] args) {

        BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(10);
        ThreadFactory factory = r -> new Thread(r, "test-thread-pool");
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                5,
                5,
                0,
                TimeUnit.MILLISECONDS,
                queue, factory,
                new ThreadPoolExecutor.CallerRunsPolicy()
        );

        for (int i = 0; i < 1000; i++) {
            executor.submit(() -> {
                try {
                    System.out.println(Thread.currentThread().getName() + ":执行任务");
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
    }

}

运行结果如下:

 前三种都适用于并发量高的业务,但是第四种适用于业务重要的场景,不能够丢失数据

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

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

相关文章

亚马逊平台买家注册流程

在亚马逊平台注册买家号是比较简单的。以下是亚马逊买家注册流程&#xff1a; 1、打开亚马逊网站&#xff1a;访问亚马逊的官方网站&#xff0c;如果要注册美国买家号&#xff0c;那么网址就是www.amazon.com。 2、点击"注册"&#xff1a;在亚马逊首页的右上角&…

LLM - 搭建 ProteinGPT 结合蛋白质结构 PDB 知识的行业 ChatGPT 系统

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://blog.csdn.net/caroline_wendy/article/details/131403263 论文&#xff1a;ProteinChat: Towards Enabling ChatGPT-Like Capabilities on Protein 3D Structures 工程&#xff1a;ht…

C语言学习(二十九)---内存操作函数

在上一节内容中&#xff0c;我们学习了有关字符串操作的函数&#xff0c;其中分为了限制长度和不限制长度两种方式&#xff0c;虽然上节内容已经在很大程度上有助于程序的实现&#xff0c;但是其有一个致命的缺陷&#xff0c;聪明的你一定已经猜到了吧&#xff0c;对的&#xf…

Linux 网络通信C/S、TCP/IP、Socket 最全详解( 9 ) -【Linux通信架构系列 】

系列文章目录 C技能系列 Linux通信架构系列 C高性能优化编程系列 深入理解软件架构设计系列 高级C并发线程编程 期待你的关注哦&#xff01;&#xff01;&#xff01; 现在的一切都是为将来的梦想编织翅膀&#xff0c;让梦想在现实中展翅高飞。 Now everything is for the…

【算法题】动态规划中级阶段之不同的二叉搜索树、交错字符串

动态规划中级阶段 前言一、不同的二叉搜索树1.1、思路1.2、代码实现 二、不同的二叉搜索树 II2.1、思路2.2、代码实现 三、交错字符串3.1、思路3.2、代码实现 总结 前言 动态规划&#xff08;Dynamic Programming&#xff0c;简称 DP&#xff09;是一种解决多阶段决策过程最优…

Pycharm中成功配置PyQt5(External Tools),设计好界面直接生成python代码

1、安装PyQt5和PyQt5-tools 在Pycharm中设置好Python环境&#xff0c;点击File-Settings-Project-Python Interpreter 设置好后退出&#xff0c;点击窗口下的Terminal&#xff0c;输入 # 直接安装输入pip install pyqt5&#xff0c;如果太慢可以用国内镜像源&#xff0c;若出…

【C++实现二叉树的遍历】

目录 一、二叉树的结构二、二叉树的遍历方式三、源码 一、二叉树的结构 二、二叉树的遍历方式 先序遍历&#xff1a; 根–>左–>右中序遍历&#xff1a; 左–>根–>右后序遍历&#xff1a;左–>右–>根层次遍历&#xff1a;顶层–>底层 三、源码 注&am…

SpringBoot04:JSR303数据校验及多环境切换

目录 一、JSR303数据校验 1、如何使用&#xff1f; 2、常见参数 二、多环境切换 1、多配置文件 2、yaml的多文档块 3、配置文件加载位置 一、JSR303数据校验 1、如何使用&#xff1f; SpringBoot中可以用Validated来校验数据&#xff0c;如果数据异常则会统一抛出异常…

python篇---统计列表中每个数字的出现次数

python篇—统计列表中每个数字的出现次数 # -*- coding: utf-8 -*- from collections import Counterlst [1, 2, 3, 3, 4, 1, 2, 5, 5, 5] count Counter(lst) print(每个数字在列表中的出现次数&#xff1a;, count) # 再将collections.Counter格式转换成dict print(dict(c…

C# 难点语法讲解之虚方法(virtual)和隐藏方法的区别---从应用需求开始讲解

这里不单独讲虚方法和隐藏方法是什么&#xff0c;很多文章都有讲&#xff0c;这里只讲他们的区别和应用理解。 另外&#xff1a;如果你不懂MonoBehaviour就别管他&#xff0c; Debug.Log就是Console.WriteLine <一>、隐藏方法 一、隐藏方法的背景故事 从前有个了不起…

C++ | 多线程资源抢占bug解决

多线程资源抢占bug解决 文章目录 多线程资源抢占bug解决bug说明原因排查解决经验>>>>> 欢迎关注公众号【三戒纪元】 <<<<< bug说明 最近调试程序&#xff0c;程序在Release版本下可运行&#xff0c;一直没有问题&#xff0c;在Debug模式下编译后…

Leetcode42 接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图&#xf…

【javascript】防止内容被复制

在JavaScript中&#xff0c;我们可以使用onselectstart事件来防止页面内容被选取。此时无法选取所要的内容。 代码&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8"><script>window.onload function() {document.bod…

计算机网络————网络层

文章目录 网络层设计思路IP地址IP地址分类IP地址与硬件地址 协议ARP和RARPIP划分子网和构造超网划分子网构造超网&#xff08;无分类编址CIDR&#xff09; ICMP 虚拟专用网VPN和网络地址转换NATVPNNAT 网络层设计思路 网络层向上只提供简单灵活的、无连接的、尽最大努力交付的数…

mysql表中出现特殊符号(逗号,点号),如何进行查询或操作

mysql表中出现特殊符号&#xff08;逗号&#xff0c;点号&#xff09;&#xff0c;如何进行查询或操作 一、背景说明二、需要把表"引"起来&#xff0c;tab键上面的那个按钮&#xff0c;不是引号 一、背景说明 当mysql表名中出现如点号&#xff08;.&#xff09;&…

安装并使用docker

1、安装docker 1.1、更新现有的包列表&#xff1a; sudo apt update 1.2、用apt安装一些允许通过HTTPS才能使用的软件包&#xff1a; sudo apt install apt-transport-https ca-certificates curl software-properties-common 1.3、将官方Docker存储库的GPG密钥添加到您的系统…

二.Elasticsearch进阶

建议从这里开始看&#xff1a;Elasticsearch快速入门及使用 Elasticsearch进阶 一.Elasticsearch检索方式1.uri 检索参数(不常用)2.uri 请求体(常用&#xff0c;也叫Query DSL) 二.Query DSL语法举例1.match全文匹配2.match_phrase短语匹配3.multi_match多字段匹配4.bool复合…

在Gradio中创建交互式代码编辑器:介绍Code模块和其功能

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

Matlab评价模型--灰色关联度分析

评价模型–灰色关联度分析 灰色关联度分析 基本思想 灰色关联分析的基本思想 是根据序列曲线几何形状的相似程度来判断其联系是否紧密&#xff0c;曲线越接近&#xff0c;相应序列之间的关联度就越大&#xff0c;反之则越小。 此方法可用于 进行系统分析&#xff0c;也可应用…

uniapp顶部导航栏被遮住显示问题

解决uniapp顶部导航栏被遮住显示问题 uniapp官方给了处理的方案&#xff0c;即css变量&#xff0c;–status-bar-height&#xff0c;小程序这个值是25px&#xff0c;app则根据实际情况去变化 如下&#xff1a; //头部导航栏 <view class"header"> </view…