【Java笔记】阿里规范-线程池创建

本文详细介绍了如何在Java中使用ThreadPoolExecutor自定义线程池,包括七大参数的设置(如核心线程数、最大线程数、阻塞队列和拒绝策略),并提供了Spring框架下的创建示例,以及线程池的生命周期管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用ThreadPoolExecutor自定义线程池

一.七大参数

  1. 核心线程:必须大于0,一直存在的线程,不会被关闭
  2. 最大线程:一般设置大于或者等于核心线程,不能小于核心线程,最大线程数=核心线程数+普通线程数,普通线程数在等待时间满后会自动关闭,节省开销
  3. 处理时间:每个线程处理任务的最大时间,普通线程超过该时间会shutDown
  4. 时间单位:处理时间的单位,一般设置为秒
  5. 阻塞队列:选择缓存队列的方式,未处理的任务会在阻塞队列里面等待线程执行
  6. 线程:使用线程工程创建线程,可以命名,方便运行区分线程属于哪个线程池的
  7. 拒绝策略:当阻塞队列满了,无法继续添加任务且工作线程等于最大线程时执行拒绝策略,有4种方式,推荐使用CallerRunsPolicy,当队列满时,添加进来的任务会重新调度给main线程进行处理,也就是不在线程池中创建的线程执行,此时任务不属于异步实现,相当于运行了线程的run方法,而不是start.

二.核心参数设置

//在 Java 中,通过 Runtime 类可以获取与系统运行时环境相关的信息和进程控制功能。其中的 getRuntime() 方法可以返回当前程序正在运行的 Java 虚拟机(JVM)的运行时实例。通过这个实例,我们可以调用 availableProcessors() 方法来获取当前系统中可用的处理器数量。

//核数
int processorAmount = Runtime.getRuntime().availableProcessors();

1.核心线程: 推荐使用以下方式设置核心线程,根据系统可用的核心处理器数量*2 +1

(CPU密集:核心线程数=CPU内核数 + 1)

(IO密集: 核心线程数=CPU内核数 * 2)

int coreThreadSize = processorAmount * 2 + 1;

2.最大线程数:推荐核心线程数+核心线程数/2

int maxThreadSize = coreThreadSize + (coreThreadSize / 2);

3.阻塞队列:常用有界队列,ArrayBlockingQueue,需要设置队列大小

4.拒绝策略:

        a. 处理日志无关紧要,稍微缺失一些不影响业务的使用:DiscardPolicy

        b. 处理实时性且效率高的,不容新提交的任务不被执行,使用:AbortPolicy(默认策略),任务队列满,无法提交新的任务时,会抛出异常:RejectedExecutionException 拒绝任务提交

        c. 当队列满无法提交新的任务时,允许新的任务在提交任务的线程中执行,即提交者线程执行,可以使用:CallerRunsPolicy策略,任务必须被执行,可能会影响一些效率

        d. 当队列已经满了,无法提交新的任务且可以将最新提交的任务抛弃,然后将任务放入队列,可以使用:DiscardOldestPolicy

选择合适的拒绝策略要根据具体的业务需求来决定。例如,当对任务处理实时性要求很高时可以选择 AbortPolicy,当需要提交者参与任务执行时可以选择 CallerRunsPolicy,当可以接受任务丢失时可以选择 DiscardPolicy,而当希望保留最新提交的任务时可以选择 DiscardOldestPolicy。

三.创建线程池

import org.jetbrains.annotations.NotNull;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Configuration
@EnableAsync
public class CommitExecutor {

    //最大的缓存任务数
    private static final int MAXIMUM_CACHED_AMOUNT = 20000;
    //核数
    int processorAmount = Runtime.getRuntime().availableProcessors();
    //核心线程数量
    int coreThreadSize = processorAmount * 2 + 1;
    //最大线程数量
    int maxThreadSize = coreThreadSize + (coreThreadSize / 2);

//    ThreadPoolExecutor executor=new ThreadPoolExecutor(
//            coreThreadSize,
//            maxThreadSize,
//            60,
//            TimeUnit.SECONDS,
//            new ArrayBlockingQueue<>(MAXIMUM_CACHED_AMOUNT),
//            new ThreadFactory() {
//                @Override
//                public Thread newThread(@NotNull Runnable r) {
//                    return new Thread(r);
//                }
//            },
//            new ThreadPoolExecutor.CallerRunsPolicy()
//    );
//
//
//    public void execute(Runnable task) {
//        executor.execute(task);
//    }

    @Bean(Constant.SYNC_EXECUTOR)
    public Executor syncExecutor(){
        return new ThreadPoolExecutor(
                coreThreadSize,
                maxThreadSize,
                60,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(MAXIMUM_CACHED_AMOUNT),
                new ThreadFactory() {
                    @Override
                    public Thread newThread(@NotNull Runnable r) {
                        return new Thread(r,Constant.SYNC_EXECUTOR);
                    }
                },
                new ThreadPoolExecutor.CallerRunsPolicy()
        );
    }

}

四.线程池生命周期

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值