首页 分类

线程池选型
● 在Spring中,我们可以利用ThreadPoolTaskExecutor配合@Async注解来实现线程池(不太建议)
ps.虽然Spring框架提供了线程池的实现,但并不特别推荐使用。因为Spring毕亮是一个框架,它进行了一定程度的封装,可能隐藏了一些细节。更推荐大家直接使用java并发包中的线程池,这也是公司常用的做法。

● 在Java中,可以使用JUC并发编程包中的ThreadPoolExecutor,.来实现非常灵活地自定义线程池。
ps.建议学完SpringBoot并能够实现一个项目,以及学完Redis之后,再系统学习Java并发编程JUC)。这样可以避免过早的压力和困扰,在具备一定实践基础的情况下,更好地理解并发编程的概念和应用。
线程池参数
● 第一个参数corePoolSize(核心线程数。这些线程就好比是公司的正式员工,他们在正常情况下都是随时待命处理任务的。如何去设定这个参数呢?比如,如果我们的服务只允许四个任务同时进行,那么我们的核心线程数应该就被设置为四。
● 第二个参数maximumPoolSize(最大线程数)。在极限情况下我们的系统或线程池能有多少个线程在工作。就算任务再多,你最多也只能雇佣这么多的人,因为你需要考虑成本和资源的问题。假设AI服务最多只允许四个任务同时执行,那么最大线程数应当设置为四。
● 第三个参数keepAliveTime(空闲线程存活时间)。这个参数决定了当任务少的时候,临时雇佣的线程会等待多久才会被别除。这个参数的设定是为了释放无用的线程资源。你可以理解为,多久之后会“解雇“"没有任务做的临时工。
● 第四个参数TimeUnit(空闲线程存话时间的单位)。将keepAliveTime和TimeUnit组合在一起,就能指定一个具体的时间,比如说分钟、秒等等。
● 第五个参数workQueue工作队列,也就是任务队列。这个队列存储所有等待执行的任务。也可以叫它阻塞队列,因为线程需要按顺序从队列中取出任务来执行。这个队列的长度一定要设定,因为无限长度的队列会消耗大量的系统资源。
● 第六个参数threadFactory(线程工厂)。它负责控制每个线程的生成,就像一个管理员,负责招聘、管理员工,比如设定员工的名字、工资,或者其他属性。
● 第七个参数RejectedExecutionHandler(拒绝策略)。当任务队列已满的时候,我们应该怎么处理新来的任务?是抛出异常,还是使用其他策略?比如说,我们可以设定任务的优先级,会员的任务优先级更高。如果你的公司或者产品中有会员业务,或者有一些重要的业务需要保证不被打扰,你可以考虑定义两个线程池或者两个任务队列,一个用于处理VIP任务,一个用于处理普通任务,保证他们不互相干扰,也就是资源隔离策略。(可以写到简历上的点)

package com.yupi.springbootinit.config;

import org.jetbrains.annotations.NotNull;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Configuration
public class ThreadPoolExecutorConfig {

@Bean
public ThreadPoolExecutor threadPoolExecutor() {
    // 创建一个线程工厂
    ThreadFactory threadFactory = new ThreadFactory() {
        // 初始化线程数为 1
        private int count = 1;

        @Override
        // 每当线程池需要创建新线程时,就会调用newThread方法
        // @NotNull Runnable r 表示方法参数 r 应该永远不为null,
        // 如果这个方法被调用的时候传递了一个null参数,就会报错
        public Thread newThread(@NotNull Runnable r) {
            // 创建一个新的线程
            Thread thread = new Thread(r);
            // 给新线程设置一个名称,名称中包含线程数的当前值
            thread.setName("线程" + count);
            // 线程数递增
            count++;
            // 返回新创建的线程
            return thread;
        }
    };
    // 创建一个新的线程池,线程池核心大小为2,最大线程数为4,
    // 非核心线程空闲时间为100秒,任务队列为阻塞队列,长度为4,使用自定义的线程工厂创建线程
    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 4, 100, TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(4), threadFactory);
    // 返回创建的线程池
    return threadPoolExecutor;
}

}



文章评论