线程池的创建&&工作机制

1、线程池的作用

为什么需要线程池:

  1. 线程的管理比较复杂(比如什么时候新增线程、什么时候减少空闲线程)
  2. 任务存取比较复杂(什么时候接受任务、什么时候拒绝任务、保证多线程不抢到同一个任务)

线程池的作用:轻松管理线程、协调任务的执行过程

2、线程池的创建和使用

2.1自己写线程池:

线程池的实现是很麻烦的,有些大厂的面试题会要我们实现线程池,这个时候就可以根据线程池的作用来分析编写啦.(比如什么时候新增线程、什么时候减少空闲线程)

2.2使用Java提供的或者第三方提供的

不用自己写,如果是在Spring中,可以用ThreadPoolTaskExecutor配合Async注解来实现。(不太建议)
如果是在Java中,可以使用JUC并发编程包中的ThreadPoolExecutor来实现非常灵活地自定义线程池。

Java线程池有七大参数

public ThreadPoolExecutor(
        int corePoolSize,
        int maximumPoolSize,
        long keepAliveTime,
        TimeUnit unit,
        BlockingQueue<Runnable> workQueue,
        ThreadFactory threadFactory,
        RejectedExecutionHandler handler
) 
2.2.1线程池的参数含义

怎么确定线程池参数?结合实际情况(实际业务场景和系统资源)来测试调整,不断优化、
回归到该系统中,考虑该系统最脆弱的环节(系统的瓶颈)在哪里?
现有条件:比如AI生成能力的并发是允许4个任务同时去执行,AI能力允许20个任务排队

int corePoolSize(核心线程数):正常情况下,系统应该能同时工作的线程数(随时就绪状态)
int maximumPoolSize(最大线程数):极限情况下,线程池可容纳的最多线程
long keepAliveTime(空闲线程存活时间):非核心线程在没有任务的情况下,过多久要删除,释放无用的资源
TimeUnit unit(空闲线程存活时间的单位):分钟、秒
BlockingQueue workQueue(工作队列):用于存放给线程执行的任务的队列,该队列应当设置长度,不能为无限队列,那样也会占用额外的资源
ThreadFactory threadFactory(线程工厂):控制每个线程的生成、线程的属性(比如线程名)
RejectedExecutionHandler handler(拒绝策略):任务队列满的时候,采取什么措施。抛异常?不抛异常?自定义策略?

资源隔离策略:比如重要的任务(VIP任务)一个队列,普通任务一个队列,保证这两个队列互不干扰

2.2.2线程池工作机制

这里有用例图解说版 和 流程图版的
用例图解说版:没那么直观,但也清晰,细节到位
流程图版:更清晰直观,当部分细节没有

推荐两个都看

用例图解说:

刚开始,没有任何的线程,也没有任何的任务:
在这里插入图片描述



来了一个任务,发现我们的员工还没有达到正式员工数(corePoolSize = 2),来一个员工直接处理这个任务
在这里插入图片描述



又来了一个任务,发现我们的员工还没有达到正式员工数(corePoolSize = 2),再来一个员工直接处理这个任务
在这里插入图片描述


又来了一个任务,但是我们正式员工数已经满了(当前线程数 = corePoolSize = 2),任务放到队列(最大长度 workQueue.size 是 2)里等待,而不是再加新员工。
在这里插入图片描述



又来了一个任务,但是我们的任务队列已经满了(当前线程数 > corePoolSize = 2,已有任务数 = 最大长度 workQueue.size = 2),新增线程(maximumPoolSize = 4)来处理新任务,而不是丢弃任务
在这里插入图片描述



已经到了任务 7,但是我们的任务队列已经满了、临时工也招满了(当前线程数 = maximumPoolSize = 4,已有任务数 = 最大长度 workQueue.size = 2),调用 RejectedExecutionHandler 拒绝策略来处理多余的任务。
在这里插入图片描述


如果当前线程数超过 corePoolSize(正式员工数),又没有新的任务给他,那么等 keepAliveTime 时间达到后,就可以把这个线程释放。

流程图:



2.2.3线程池的参数如何设置

现有条件:比如AI生成能力的并发是允许4个任务同时去执行,AI能力允许20个任务排队
int corePoolSize(核心线程数):正常情况下,可以设置为2-4
int maximumPoolSize(最大线程数):设置为极限情况<=4
long keepAliveTime(空闲线程存活时间):一般为秒级或分钟级
TimeUnit unit(空闲线程存活时间的单位):分钟、秒
BlockingQueue workQueue(工作队列):结合实际情况去设置,可以设置为20
RejectedExecutionHandler handler(拒绝策略):抛异常,标记数据库的任务状态为“任务满了已拒绝”

一般情况下,任务分为IO密集型和计算密集型两种
计算密集型:吃CPU,比如音视频处理、图像处理、数学计算等,一般设置corePoolSize为CPU核心数+1(空余线程),可以让每个线程都能利用好CPU的每个核,而且线程之间不用频繁切换
IO密集型:吃带宽/内存/硬盘等资源,corePoolSize可以设置大一些,一般为2n左右,但是建议以IO能力为主
例:导入百万数据到数据库属于IO密集型任务

2.2.4调试

自定义线程池:

@Configuration
public class ThreadPoolExecutorConfig {
    @Bean
    public ThreadPoolExecutor threadPoolExecutor() {
        ThreadFactory threadFactory = new ThreadFactory() {
            private int count = 1;

            @Override
            public Thread newThread(@NotNull Runnable r) {
                Thread thread = new Thread(r);
                thread.setName("线程" + count);
                count++;
                return thread;
            }
        };
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 4, 100, TimeUnit.SECONDS, new ArrayBlockingQueue<>(4), threadFactory);
        return threadPoolExecutor;
    }

提交任务到线程池:

@GetMapping("/add")
public void add(String name) {
    CompletableFuture.runAsync(() -> {
        System.out.println("任务执行中:" + name + ",执行人:" + Thread.currentThread().getName());
        try {
            Thread.sleep(60000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    },threadPoolExecutor);
}

相关推荐

  1. 线创建方式

    2024-04-29 17:58:05       39 阅读
  2. Linux:线创建和基本使用

    2024-04-29 17:58:05       32 阅读
  3. python中线/线,进程/进程创建

    2024-04-29 17:58:05       50 阅读
  4. springboot如何创建全局线

    2024-04-29 17:58:05       53 阅读
  5. 一个线进入线工作流程

    2024-04-29 17:58:05       25 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-29 17:58:05       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-29 17:58:05       100 阅读
  3. 在Django里面运行非项目文件

    2024-04-29 17:58:05       82 阅读
  4. Python语言-面向对象

    2024-04-29 17:58:05       91 阅读

热门阅读

  1. mysql基础sql

    2024-04-29 17:58:05       24 阅读
  2. 单例模式及其应用

    2024-04-29 17:58:05       34 阅读
  3. jenkins自动化举例

    2024-04-29 17:58:05       25 阅读
  4. c++设计模式

    2024-04-29 17:58:05       28 阅读
  5. 力扣1146 快照数组

    2024-04-29 17:58:05       39 阅读
  6. LINUX 系统编程 局域网聊天室项目

    2024-04-29 17:58:05       28 阅读
  7. 抖音运营必备:作品发布必知的6大注意事项!

    2024-04-29 17:58:05       32 阅读
  8. Python中的map()和filter()函数:深入解析与使用场景

    2024-04-29 17:58:05       128 阅读
  9. python打印金字塔

    2024-04-29 17:58:05       134 阅读
  10. AI智能体的未来:引领科技创新潮流

    2024-04-29 17:58:05       27 阅读
  11. Support contact(DayMatter App)

    2024-04-29 17:58:05       37 阅读
  12. 同步与异步

    2024-04-29 17:58:05       36 阅读