首页 > 其他分享 >线程池

线程池

时间:2024-03-03 23:33:21浏览次数:22  
标签:ThreadFactory 队列 创建 corePoolSize 任务 线程

线程池——治理线程的法宝

1. 线程池的自我介绍

  • 线程池的重要性

  • 什么是池

    • 软件中的“池”,可以理解为计划经济

    • 如果不使用线程池,每个任务都新开一个线程处理

      • 一个线程
      • for循环创建线程
      • 当任务数量上升到1000
    • 这样的开销太大,我们希望有固定数量的线程,来执行这1000个线程,这样就避免了反复创建并销毁线程所带来的开销问题

为什么要使用线程池

问题一:反复创建线程开销大

问题二:过多的线程会占用太多内存

  • 解决以上两个问题的思路
    • 用少量的线程——避免内存占用过多
    • 让这部分线程都保持工作,且可以反复执行任务——避免生命周期的损耗

线程池的好处

  • 加速响应速度
  • 合理利用CPU和内存(灵活配置达到性能最佳状态)
  • 统一管理

线程池适合应用的场景

  • 服务器接受到大量请求时,使用线程池技术是非常合适的。它可以大大减少线程的创建和销毁次数,提搞服务器的工作效率。

2. 创建和停止线程

线程池构造函数的参数

参数名 类型 含义
corePoolSize int 核心线程数
maxPoolSize int 最大线程数
KeepAliveTime long 保持存活时间
workQueue BlockQueue 任务存储队列
ThreadFactory ThreadFactory 当线程池需要新的线程的时候,会使用threadFactory来生成新的线程
Handler RejectExecutionHandler 由于线程池无法接收新提交的任务的拒绝策略
  • corePoolSize:指的是核心线程数,线程池在初始化后,默认情况下,线程池中并没有任何线程,线程池会等待有任务到来时,在创建新线程去执行任务。
  • maxPoolSize:线程池有可能会在核心线程数的基础上,额外增加一些线程,但是这些新增加的线程数有一个上限,这就是最大量maxPoolSize。
  • KeepAliveTime:如果线程池当前的线程数多于corePoolSize,那么多于的线程空闲时间超过KeepAliveTime,它们就会终止。

image-20240229220555353

如上图所示,core Pool Size为初始化线程池容量大小,随着线程数量的增加,当前线程数会增加,直到等于最大线程数。

添加线程规则

image-20240302232528093

如果用流程图来描述如下图

image-20240229220819847

根据上图可知,是否需要增加线程的判断顺序是:

  • corePoolSize
  • workQueue
  • maxPoolSize

image-20240229221006018

增减线程的特点

  1. 通过设置corePoolSize和maximumPoolSize相同,就可以创建固定大小的线程池。如newFixThreadPool
  2. 线程池希望保持较少的线程数,并且只有在负载变得很大时才增加它。
  3. 通过设置maximumPoolSize为很高的值,例如 Integer.MAX_VALUE。才可以允许线程池容纳任意数量的并发任务。
  4. 只有在队列填满时才创建多于corePoolSize的线程,所以如果使用的是无界队列(例如LinkedBlockQueue),那么线程数就不会超过corePoolSize。

image-20240229221220451

  • ThreadFactory:新的线程是由ThreadFactory创建的,默认使用Executors.defaultThreadFactor(),创建出来的线程都在同一个线程组,拥有同样的NORM PRIORITY优先级并且都不是守护线程。如果自己指定ThreadFactory,那么就可以改变线程名、线程组、优先级、是否是守护线程等。

image-20240229221648319

  • WorkQueue工作队列

1)直接交换:SynchronousQueue,maxPool需要设置大一些,无队列作为缓冲。

2)无界队列:LinkedBlockingQueue,若处理速度 < 存放队列速度,一直存放,会OOM

3)有界队列:ArrayBlockingQueue

image-20240302233903257

线程池应该手动创建还是自动创建

线程池里的线程数量设定为多少比较合适

停止线程池的正确方式

3. 常见线程池的特点和用法

4.任务太多,怎么拒绝

  • 拒绝时机
    • 1.当Executor关闭时,提交新任务被拒绝
    • 2.当Executor对最大线程和工作队列使用有限边界并且已经饱和

四种拒绝策略

  • AbortPolicy:直接抛出异常
  • Discardpolicy:丢弃
  • DiscardOldestPolicy:丢掉最老(早)的任务
  • CallerRunsPolicy:谁提交任务,谁跑该线程

5.钩子方法,给线程池加点料

6.实现原理、源码分析

7. 使用线程池的注意点

  • 避免任务的堆积
  • 避免线程数过度增加
  • 排查线程泄露

标签:ThreadFactory,队列,创建,corePoolSize,任务,线程
From: https://www.cnblogs.com/shine-rainbow/p/18050996

相关文章

  • python中的多线程及锁介绍
    线程CPU执行调度的最小单位。不能独立存在,依赖进程存在。一个进程至少有一个线程,叫做主线程,另外还有内核线程、用户线程。线程之间共享内存。线程之间的通信效率远高于进程间通信效率,线程之间切换代价也比进程小很多。适用场景Python的多线程适用于IO密集型任务。多任务可以......
  • 多线程限流工具类-Semaphore
    Semaphore介绍Semaphore(信号量)是JAVA多线程中的一个工具类,它可以通过指定参数来控制执行线程数量,一般用于限流访问某个资源时使用。Semaphore使用示例需求场景:用一个核心线程数为6,最大线程数为20的线程池执行任务,但是要求最多只能同时运行3个线程代码:publicclassdemo{......
  • C#多线程
    在C#编程中,多线程是实现高效并发编程的关键技术之一。通过创建多个线程,程序可以同时执行多个任务,从而充分利用多核处理器的计算能力。本文将带你快速回顾C#多线程的基础知识,通过10分钟的学习,你将能够掌握多线程的核心概念,并学会使用C#语言创建和管理线程。一、多线程基础概念在C......
  • 并发编程补充:基于多线程实现并发的套接字通信
    服务端:fromsocketimport*fromthreadingimportThreaddefcommunicate(conn):whileTrue:try:data=conn.recv(1024)ifnotdata:breakconn.send(data.upper())exceptConnectionResetError:......
  • 对于需要实时处理的代码语句 就用定时器中断模式,实现多线程模式,建议不要用查询模式。
    对于需要实时处理的代码语句就用定时器中断模式,实现多线程模式,建议不要用查询模式。 示例代码1:查看代码#include"delay.h"#include"sysInt.h"#include"intrins.h"charSMGDuan[]={0x5B,0x3F,0x5B,0x66, 0x40,0x40, 0x3F,0x3F}; //2024--MMcharsegDuan[]={0x3F,0......
  • pyqt5中多线程爬虫
       设立爬虫Class,继承pyqt5中的Thread函数中使用普通线程  整体代码:importsysimportpandasaspdimportjson,requests,time,threadingfromPyQt5.QtWidgetsimportQMainWindow,QApplication,QVBoxLayout,QMessageBoxfromui.ui_testimportUi_MainWind......
  • c++多线程按行读取同一个每行长度不规则文件
    对于非常大的比如上百G的大文件读取,单线程读是非常非常慢的,需要考虑用多线程读,多个线程读同一个文件时不用加锁的,每个线程打开一个独立的文件句柄多线程读同一个文件实现思路思路1先打开一个文件句柄,获取整个文件大小file_size确定要采用线程读取的部分大小read_size和......
  • c++多线程编程
    c++线程库:<thread>创建线程:需要可调用的函数或者函数对象作为线程入口点例:std::threadthreadname(function_name,args...)在C++中,当使用std::thread创建线程并传递类的成员函数时,需要使用&来获取成员函数的地址,同时还需要传递对象的指针(或引用)作为第一个参数。......
  • HashMap很美好,但线程不安全怎么办?ConcurrentHashMap告诉你答案!
    写在开头在《耗时2天,写完HashMap》这篇文章中,我们提到关于HashMap线程不安全的问题,主要存在如下3点风险:风险1:put的时候导致元素丢失;如两个线程同时put,且key值相同的情况下,后一个线程put操作覆盖了前一个线程的操作,导致前一个线程的元素丢失。风险2:put和get并发时会导致g......
  • C++ 多线程笔记2 线程同步
    C++多线程笔记2线程同步并发(Concurrency)和并行(Parallelism)并发是指在单核CPU上,通过时间片轮转的方式,让多个任务看起来像是同时进行的。实际上,CPU在一个时间段内只会处理一个任务,但是由于切换时间非常快,用户感觉像是多个任务同时在进行。这种方式的优点是可以充分利用CPU资源,......