专业的JAVA编程教程与资源

网站首页 > java教程 正文

你真的会用 Java 中的线程池吗?多个企业级线程池工具类封装实践

temp10 2025-07-09 17:28:35 java教程 3 ℃ 0 评论

在 Java 多线程编程领域,线程池是一项极为重要的技术。它通过复用已创建的线程,避免频繁创建和销毁线程带来的开销,从而提升系统性能和资源利用率。然而,在实际企业级开发中,许多开发者对线程池的使用仅仅停留在基础层面,未能充分发挥其潜力。本文将深入探讨 Java 线程池的核心原理,并分享企业级线程池工具类的封装实践,帮助你掌握线程池的高级应用。

一、Java 线程池核心原理剖析

Java 线程池的核心实现类是ThreadPoolExecutor,它的构造函数包含 7 个关键参数,这些参数决定了线程池的行为和特性:

你真的会用 Java 中的线程池吗?多个企业级线程池工具类封装实践

  1. corePoolSize:核心线程数,线程池启动后会创建的线程数量,即使这些线程处于空闲状态也不会被销毁。
  1. maximumPoolSize:最大线程数,线程池允许创建的最大线程数量。当任务队列已满且已创建的线程数小于最大线程数时,线程池会创建新的线程来处理任务。
  1. keepAliveTime:空闲线程存活时间,当线程池中的线程数量大于核心线程数时,空闲线程在超过该时间后会被销毁。
  1. unit:keepAliveTime的时间单位,如TimeUnit.SECONDS(秒)、TimeUnit.MILLISECONDS(毫秒)等。
  1. workQueue:任务队列,用于保存等待执行的任务。常见的任务队列有ArrayBlockingQueue(有界队列)、LinkedBlockingQueue(无界队列)等。
  1. threadFactory:线程工厂,用于创建新线程,通过自定义线程工厂可以设置线程的名称、优先级等属性。
  1. handler:拒绝策略,当任务队列已满且线程数量达到最大线程数时,线程池会根据该策略处理新提交的任务。常见的拒绝策略有AbortPolicy(抛出异常)、CallerRunsPolicy(由调用线程处理任务)等。

线程池处理任务的流程如下:

  1. 当提交一个任务时,线程池首先检查核心线程是否都在忙碌。如果有空闲的核心线程,则直接分配任务给该线程执行。
  1. 如果核心线程都在忙碌,且任务队列未满,则将任务放入任务队列等待执行。
  1. 如果任务队列已满,且线程数量小于最大线程数,则创建新的线程来执行任务。
  1. 如果任务队列已满且线程数量达到最大线程数,则根据设置的拒绝策略处理新提交的任务。

二、企业级线程池工具类封装实践

在企业级开发中,为了方便管理和复用线程池,通常会对ThreadPoolExecutor进行封装,创建一个通用的线程池工具类。以下是一个简单但实用的线程池工具类示例:

import java.util.concurrent.*;
public class ThreadPoolUtil {
    // 核心线程数,根据CPU核心数动态调整
    private static final int CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors() + 1;
    // 最大线程数
    private static final int MAX_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 2 + 1;
    // 空闲线程存活时间
    private static final long KEEP_ALIVE_TIME = 10L;
    // 时间单位
    private static final TimeUnit UNIT = TimeUnit.SECONDS;
    // 任务队列
    private static final BlockingQueue<Runnable> WORK_QUEUE = new LinkedBlockingQueue<>(1000);
    // 线程工厂
    private static final ThreadFactory THREAD_FACTORY = new ThreadFactoryBuilder()
           .setNameFormat("custom-thread-pool-%d")
           .build();
    // 拒绝策略
    private static final RejectedExecutionHandler HANDLER = new ThreadPoolExecutor.CallerRunsPolicy();
    // 单例模式的线程池实例
    private static final ThreadPoolExecutor THREAD_POOL_EXECUTOR;
    static {
        THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(
                CORE_POOL_SIZE,
                MAX_POOL_SIZE,
                KEEP_ALIVE_TIME,
                UNIT,
                WORK_QUEUE,
                THREAD_FACTORY,
                HANDLER
        );
    }
    // 提交任务
    public static void execute(Runnable task) {
        THREAD_POOL_EXECUTOR.execute(task);
    }
    // 提交任务并获取Future
    public static <T> Future<T> submit(Callable<T> task) {
        return THREAD_POOL_EXECUTOR.submit(task);
    }
    // 关闭线程池
    public static void shutdown() {
        THREAD_POOL_EXECUTOR.shutdown();
        try {
            if (!THREAD_POOL_EXECUTOR.awaitTermination(60, TimeUnit.SECONDS)) {
                THREAD_POOL_EXECUTOR.shutdownNow();
            }
        } catch (InterruptedException e) {
            THREAD_POOL_EXECUTOR.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }
}

假设我们正在开发一个电商系统,用户提交商品评论后,需要对评论进行一系列处理,如敏感词过滤、评论审核、积分计算等。为了不阻塞用户提交评论的主流程,提高系统响应速度,我们可以使用ThreadPoolUtil工具类将评论处理任务异步化。

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
public class EcommerceCommentBusiness {
    public static void main(String[] args) {
        // 模拟用户提交的评论内容
        String comment = "这款商品质量非常好,很满意!";
        // 提交无返回值的评论处理任务,比如敏感词过滤
        ThreadPoolUtil.execute(() -> {
            System.out.println("开始进行评论敏感词过滤...");
            // 模拟敏感词过滤操作,这里简单打印
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("评论敏感词过滤完成");
        });
        // 提交有返回值的评论处理任务,比如评论审核并返回审核结果
        Future<Boolean> resultFuture = ThreadPoolUtil.submit(() -> {
            System.out.println("开始进行评论审核...");
            // 模拟评论审核逻辑,这里简单返回true表示审核通过
            try {
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return true;
        });
        try {
            boolean isApproved = resultFuture.get();
            if (isApproved) {
                System.out.println("评论审核通过");
                // 提交评论审核通过后的积分计算任务
                ThreadPoolUtil.execute(() -> {
                    System.out.println("开始计算评论积分...");
                    // 模拟积分计算操作,这里简单打印
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("评论积分计算完成");
                });
            } else {
                System.out.println("评论审核未通过");
            }
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        // 当系统关闭时,优雅关闭线程池
        ThreadPoolUtil.shutdown();
    }
}

在上述示例中:

  1. 首先定义了一个模拟的用户评论内容。
  1. 使用ThreadPoolUtil.execute方法提交了一个无返回值的任务,用于模拟评论敏感词过滤操作,该任务在后台线程中执行,不会阻塞主线程。
  1. 通过ThreadPoolUtil.submit方法提交了一个有返回值的评论审核任务,并通过Future获取审核结果。根据审核结果,决定是否继续提交评论积分计算任务。
  1. 最后,在系统关闭时调用ThreadPoolUtil.shutdown方法,优雅地关闭线程池,确保正在执行的任务能妥善处理 。

通过这种方式,在电商系统的商品评论处理业务中,利用ThreadPoolUtil工具类实现了任务的异步处理,提高了系统的响应性能和用户体验。

以上示例展示了工具类在电商评论处理场景的应用。若你想尝试其他业务场景,或对任务处理逻辑有不同需求,欢迎和我分享想法。

在上述代码中,我们通过静态代码块创建了一个单例模式的线程池实例THREAD_POOL_EXECUTOR,并提供了execute和submit方法用于提交任务,以及shutdown方法用于优雅地关闭线程池。其中,核心线程数和最大线程数根据服务器的 CPU 核心数动态调整,以充分利用服务器资源;任务队列采用LinkedBlockingQueue,并设置了一定的容量;线程工厂使用ThreadFactoryBuilder来自定义线程名称;拒绝策略采用CallerRunsPolicy,即当任务队列已满且线程数量达到最大线程数时,由调用线程处理任务。

三、线程池工具类的应用场景

  1. 异步任务处理:在处理一些耗时较长且不需要立即获取结果的任务时,如日志记录、数据统计等,可以使用线程池将任务异步提交,避免阻塞主线程,提高系统的响应速度。
  1. 高并发请求处理:在 Web 应用中,当面临高并发请求时,线程池可以有效地管理线程资源,防止因线程过多导致系统资源耗尽,保证系统的稳定性和性能。
  1. 定时任务执行:结合ScheduledThreadPoolExecutor(ThreadPoolExecutor的子类),可以实现定时任务的执行,如定时清理临时文件、定时同步数据等。

四、线程池使用的注意事项

  1. 合理配置参数:线程池的参数配置需要根据具体的业务场景和服务器资源进行调整。如果核心线程数设置过小,可能导致任务堆积;如果最大线程数设置过大,可能会耗尽系统资源。
  1. 监控线程池状态:在生产环境中,建议使用一些监控工具(如 JMX、Prometheus 等)对线程池的状态进行实时监控,包括任务队列的长度、活跃线程数、已完成任务数等,以便及时发现问题并进行调整。
  1. 异常处理:在提交任务时,需要考虑任务执行过程中可能出现的异常情况,并进行适当的处理。可以通过Future获取任务执行结果和异常信息,或者在任务中捕获异常并进行处理。

五、多线程实战

在 Java 开发中,线程池参数的合理设置对系统性能和稳定性起着决定性作用。不同的业务需求对应着不同的线程池参数配置方式,只有精准匹配,才能充分发挥线程池的优势。接下来,我们将从各类常见业务场景出发,探讨如何调整线程池的核心参数。

一、CPU 密集型业务

CPU 密集型任务指的是那些大部分时间都在使用 CPU 进行计算的任务,如复杂的数学运算、加密解密操作等。这类任务的特点是 CPU 使用率高,线程在执行过程中很少会因为 I/O 操作等原因阻塞。

  • 核心线程数:为了充分利用 CPU 资源,同时避免线程过多导致上下文切换开销过大,核心线程数通常设置为 CPU 核心数加 1。例如,对于 4 核 CPU 的服务器,corePoolSize可设置为 5。这样当一个线程在执行计算任务时偶尔出现短暂的非 CPU 操作(如读取少量数据),额外的一个线程可以立即被调度执行,从而保证 CPU 始终处于忙碌状态。
  • 最大线程数:由于 CPU 资源有限,过多的线程反而会降低性能,因此maximumPoolSize一般与corePoolSize保持一致或略大,如设置为 6。
  • 任务队列:因为 CPU 密集型任务执行速度相对较快,任务队列不易积压,可选择较小容量的有界队列,如ArrayBlockingQueue,容量设置为 10 - 20 左右即可 。
  • 拒绝策略:考虑到这类任务对实时性要求较高,通常采用AbortPolicy拒绝策略,当任务无法提交时立即抛出异常,以便开发者及时处理。

二、I/O 密集型业务

I/O 密集型任务是指任务在执行过程中大部分时间都在等待 I/O 操作完成,如文件读写、网络请求等。由于 I/O 操作速度远慢于 CPU 处理速度,线程在等待 I/O 时处于空闲状态,此时可以利用更多线程来提高系统吞吐量。

  • 核心线程数:一般可将核心线程数设置为 CPU 核心数的 2 - 3 倍。例如 4 核 CPU 的服务器,corePoolSize可设置为 8 - 12。因为在 I/O 等待期间,核心线程可以释放出来执行其他任务,增加核心线程数能有效利用 CPU 资源。
  • 最大线程数:可以适当增大maximumPoolSize,如设置为 CPU 核心数的 5 - 8 倍,以应对突发的高并发 I/O 请求。但也要注意不能设置过大,否则会占用过多系统资源。
  • 任务队列:由于 I/O 操作耗时不确定,可能会导致任务队列积压,所以宜选择容量较大的队列,如LinkedBlockingQueue,容量可根据实际业务流量预估,例如设置为 100 - 500 。
  • 拒绝策略:如果业务允许一定程度的延迟处理,可采用CallerRunsPolicy拒绝策略,将任务回退到调用线程执行,减轻线程池压力;若对任务处理实时性要求较高,则可使用AbortPolicy。

三、混合型业务

在实际企业应用中,更多的是混合型业务场景,即包含 CPU 密集型任务,也包含 I/O 密集型任务。

  • 核心线程数:可综合考虑两种任务的比例和特性,取一个折中值。例如,若 CPU 密集型任务和 I/O 密集型任务大致各占一半,核心线程数可设置为 CPU 核心数的 1.5 - 2 倍。
  • 最大线程数:根据业务峰值流量和系统资源情况适当放宽,预留一定的扩展空间,一般可设置为核心线程数的 2 - 3 倍。
  • 任务队列:选择有界队列,容量根据业务波动情况进行设置,既能避免队列无限增长耗尽内存,又能在一定程度上缓冲突发任务。
  • 拒绝策略:结合业务对任务丢失和延迟的容忍度选择,如DiscardOldestPolicy(丢弃队列中最老的任务)或CallerRunsPolicy。

四、动态调整线程池参数

除了根据业务场景静态设置参数,在一些对实时性要求较高的场景中,还可以通过监控线程池的运行状态,动态调整参数。例如,通过 JMX 或 Prometheus 等监控工具,实时获取线程池的活跃线程数、任务队列长度等指标。当发现任务队列持续积压且活跃线程数接近最大线程数时,可以适当增大核心线程数或最大线程数;当线程池长时间空闲时,则可减少线程数量,释放系统资源。

根据业务需求调整线程池参数需要深入理解业务特点和系统资源情况。通过合理设置核心线程数、最大线程数、任务队列以及拒绝策略,并结合动态调整手段,能够让线程池在不同业务场景下都保持高效运行,为系统的稳定和性能提升提供有力保障。 综上所述,Java 线程池是一项强大而复杂的技术,深入理解其原理并合理封装和使用线程池工具类,能够显著提升企业级应用的性能和稳定性。希望本文的内容能够帮助你更好地掌握 Java 线程池的使用,在实际开发中发挥出线程池的最大价值。

六、以下是一个企业级线程池工具类的封装示例,包含配置管理、监控、异常处理、优雅关闭等功能

在企业级 Java 开发中,线程池的高效管理对于提升系统性能和稳定性至关重要。一个功能完备的线程池工具类,可以帮助开发者更便捷地管理线程资源。接下来,我们将详细介绍一个包含多种实用功能的 Java 线程池工具类,并通过一个简单业务实例展示其使用方法。

一、线程池工具类代码

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.*;
public class AdvancedThreadPoolUtil {
    // 用于存储不同业务的线程池实例,以线程池名称为键
    private static final Map<String, ThreadPoolExecutor> THREAD_POOL_MAP = new HashMap<>();
    // 配置文件名称,用于读取线程池相关配置
    private static final String CONFIG_FILE = "threadPoolConfig.properties";
    static {
        Properties properties = new Properties();
        try (InputStream inputStream = AdvancedThreadPoolUtil.class.getClassLoader().getResourceAsStream(CONFIG_FILE)) {
            if (inputStream != null) {
                // 加载配置文件内容到properties对象
                properties.load(inputStream);
            }
        } catch (IOException e) {
            // 若加载配置文件失败,抛出运行时异常
            throw new RuntimeException("Failed to load thread pool configuration", e);
        }
        // 从配置文件中获取所有线程池名称,以逗号分隔
        String[] poolNames = properties.getProperty("poolNames").split(",");
        for (String poolName : poolNames) {
            // 获取核心线程数,若配置文件未设置则使用默认值5
            int corePoolSize = Integer.parseInt(properties.getProperty(poolName + ".corePoolSize", "5"));
            // 获取最大线程数,若配置文件未设置则使用默认值10
            int maximumPoolSize = Integer.parseInt(properties.getProperty(poolName + ".maximumPoolSize", "10"));
            // 获取空闲线程存活时间,若配置文件未设置则使用默认值60
            long keepAliveTime = Long.parseLong(properties.getProperty(poolName + ".keepAliveTime", "60"));
            // 获取时间单位,若配置文件未设置则使用默认值秒
            TimeUnit unit = TimeUnit.valueOf(properties.getProperty(poolName + ".unit", "SECONDS"));
            // 获取任务队列容量,若配置文件未设置则使用默认值100
            int queueCapacity = Integer.parseInt(properties.getProperty(poolName + ".queueCapacity", "100"));
            // 获取拒绝策略,若配置文件未设置则使用默认值AbortPolicy
            String rejectPolicy = properties.getProperty(poolName + ".rejectPolicy", "AbortPolicy");
            // 创建任务队列,容量为从配置文件获取的值
            BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(queueCapacity);
            // 使用默认线程工厂创建线程
            ThreadFactory threadFactory = Executors.defaultThreadFactory();
            RejectedExecutionHandler handler;
            // 根据配置文件中的拒绝策略字符串,创建对应的拒绝策略对象
            switch (rejectPolicy) {
                case "AbortPolicy":
                    handler = new ThreadPoolExecutor.AbortPolicy();
                    break;
                case "CallerRunsPolicy":
                    handler = new ThreadPoolExecutor.CallerRunsPolicy();
                    break;
                case "DiscardPolicy":
                    handler = new ThreadPoolExecutor.DiscardPolicy();
                    break;
                case "DiscardOldestPolicy":
                    handler = new ThreadPoolExecutor.DiscardOldestPolicy();
                    break;
                default:
                    throw new IllegalArgumentException("Invalid reject policy: " + rejectPolicy);
            }
            // 使用获取到的参数创建线程池实例
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                    corePoolSize,
                    maximumPoolSize,
                    keepAliveTime,
                    unit,
                    workQueue,
                    threadFactory,
                    handler
            );
            // 将创建好的线程池实例放入THREAD_POOL_MAP中,以线程池名称作为键
            THREAD_POOL_MAP.put(poolName, threadPoolExecutor);
        }
    }
    // 提交任务到指定线程池
    public static void execute(String poolName, Runnable task) {
        // 根据线程池名称从THREAD_POOL_MAP中获取对应的线程池实例
        ThreadPoolExecutor threadPoolExecutor = THREAD_POOL_MAP.get(poolName);
        if (threadPoolExecutor == null) {
            // 若线程池不存在,抛出非法参数异常
            throw new IllegalArgumentException("ThreadPool " + poolName + " does not exist");
        }
        try {
            // 提交任务到线程池,并在任务执行出现异常时进行捕获和处理
            threadPoolExecutor.execute(() -> {
                try {
                    task.run();
                } catch (Exception e) {
                    // 打印任务执行异常信息,可根据实际需求进行更详细的日志记录
                    System.err.println("Task execution exception in pool " + poolName + ": " + e.getMessage());
                }
            });
        } catch (RejectedExecutionException e) {
            // 当线程池拒绝任务时,打印拒绝任务的异常信息
            System.err.println("Task rejected by pool " + poolName + ": " + e.getMessage());
        }
    }
    // 提交任务到指定线程池并获取Future,用于获取任务执行结果
    public static <T> Future<T> submit(String poolName, Callable<T> task) {
        // 根据线程池名称获取对应的线程池实例
        ThreadPoolExecutor threadPoolExecutor = THREAD_POOL_MAP.get(poolName);
        if (threadPoolExecutor == null) {
            // 若线程池不存在,抛出非法参数异常
            throw new IllegalArgumentException("ThreadPool " + poolName + " does not exist");
        }
        try {
            // 提交可返回结果的任务到线程池,并在任务执行出现异常时进行捕获和处理
            return threadPoolExecutor.submit(() -> {
                try {
                    return task.call();
                } catch (Exception e) {
                    // 打印任务执行异常信息,可根据实际需求进行更详细的日志记录
                    System.err.println("Task execution exception in pool " + poolName + ": " + e.getMessage());
                    throw e;
                }
            });
        } catch (RejectedExecutionException e) {
            // 当线程池拒绝任务时,打印拒绝任务的异常信息
            System.err.println("Task rejected by pool " + poolName + ": " + e.getMessage());
            throw e;
        }
    }
    // 关闭指定线程池
    public static void shutdown(String poolName) {
        // 从THREAD_POOL_MAP中移除并获取对应的线程池实例
        ThreadPoolExecutor threadPoolExecutor = THREAD_POOL_MAP.remove(poolName);
        if (threadPoolExecutor != null) {
            // 启动线程池的有序关闭流程
            threadPoolExecutor.shutdown();
            try {
                // 等待60秒,让正在执行的任务完成
                if (!threadPoolExecutor.awaitTermination(60, TimeUnit.SECONDS)) {
                    // 若60秒后任务仍未完成,立即终止所有任务
                    threadPoolExecutor.shutdownNow();
                }
            } catch (InterruptedException e) {
                // 若等待过程中线程被中断,立即终止所有任务,并恢复中断状态
                threadPoolExecutor.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
    }
    // 获取指定线程池的活跃线程数
    public static int getActiveCount(String poolName) {
        // 根据线程池名称获取对应的线程池实例
        ThreadPoolExecutor threadPoolExecutor = THREAD_POOL_MAP.get(poolName);
        if (threadPoolExecutor == null) {
            // 若线程池不存在,抛出非法参数异常
            throw new IllegalArgumentException("ThreadPool " + poolName + " does not exist");
        }
        // 返回线程池当前的活跃线程数
        return threadPoolExecutor.getActiveCount();
    }
    // 获取指定线程池的已完成任务数
    public static long getCompletedTaskCount(String poolName) {
        // 根据线程池名称获取对应的线程池实例
        ThreadPoolExecutor threadPoolExecutor = THREAD_POOL_MAP.get(poolName);
        if (threadPoolExecutor == null) {
            // 若线程池不存在,抛出非法参数异常
            throw new IllegalArgumentException("ThreadPool " + poolName + " does not exist");
        }
        // 返回线程池已完成的任务数量
        return threadPoolExecutor.getCompletedTaskCount();
    }
    // 获取指定线程池的任务队列大小
    public static int getQueueSize(String poolName) {
        // 根据线程池名称获取对应的线程池实例
        ThreadPoolExecutor threadPoolExecutor = THREAD_POOL_MAP.get(poolName);
        if (threadPoolExecutor == null) {
            // 若线程池不存在,抛出非法参数异常
            throw new IllegalArgumentException("ThreadPool " + poolName + " does not exist");
        }
        // 返回线程池任务队列中当前的任务数量
        return threadPoolExecutor.getQueue().size();
    }
    // 动态调整指定线程池的核心线程数
    public static void setCorePoolSize(String poolName, int corePoolSize) {
        // 根据线程池名称获取对应的线程池实例
        ThreadPoolExecutor threadPoolExecutor = THREAD_POOL_MAP.get(poolName);
        if (threadPoolExecutor == null) {
            // 若线程池不存在,抛出非法参数异常
            throw new IllegalArgumentException("ThreadPool " + poolName + " does not exist");
        }
        // 设置线程池的核心线程数
        threadPoolExecutor.setCorePoolSize(corePoolSize);
    }
    // 动态调整指定线程池的最大线程数
    public static void setMaximumPoolSize(String poolName, int maximumPoolSize) {
        // 根据线程池名称获取对应的线程池实例
        ThreadPoolExecutor threadPoolExecutor = THREAD_POOL_MAP.get(poolName);
        if (threadPoolExecutor == null) {
            // 若线程池不存在,抛出非法参数异常
            throw new IllegalArgumentException("ThreadPool " + poolName + " does not exist");
        }
        // 设置线程池的最大线程数
        threadPoolExecutor.setMaximumPoolSize(maximumPoolSize);
    }
}

二、配置文件示例(threadPoolConfig.properties)

# 定义多个线程池名称,以逗号分隔
poolNames=orderPool,paymentPool
# orderPool线程池的核心线程数
orderPool.corePoolSize=4
# orderPool线程池的最大线程数
orderPool.maximumPoolSize=8
# orderPool线程池的空闲线程存活时间
orderPool.keepAliveTime=20
# orderPool线程池的时间单位
orderPool.unit=SECONDS
# orderPool线程池的任务队列容量
orderPool.queueCapacity=150
# orderPool线程池的拒绝策略
orderPool.rejectPolicy=CallerRunsPolicy
# paymentPool线程池的核心线程数
paymentPool.corePoolSize=6
# paymentPool线程池的最大线程数
paymentPool.maximumPoolSize=12
# paymentPool线程池的空闲线程存活时间
paymentPool.keepAliveTime=30
# paymentPool线程池的时间单位
paymentPool.unit=SECONDS
# paymentPool线程池的任务队列容量
paymentPool.queueCapacity=200
# paymentPool线程池的拒绝策略
paymentPool.rejectPolicy=AbortPolicy

在这个配置文件中,我们为不同业务的线程池分别设置了参数。例如,orderPool用于处理订单相关任务,设置了相对较小的核心线程数和队列容量;而paymentPool用于处理支付任务,考虑到支付操作的重要性和可能的高并发,设置了较大的核心线程数和队列容量,并且采用AbortPolicy拒绝策略,当任务无法提交时立即抛出异常,以保证支付业务的准确性和可靠性。

三、简单业务实例

假设我们开发一个电商系统,其中订单处理和支付处理是两个不同的业务逻辑,需要使用不同的线程池来确保业务之间互不干扰,提高系统的稳定性和性能。

public class EcommerceBusinessExample {
    public static void main(String[] args) {
        // 模拟订单处理任务,该任务会打印处理信息并暂停1秒模拟业务操作
        Runnable orderTask = () -> {
            try {
                System.out.println("Processing order...");
                Thread.sleep(1000);
                System.out.println("Order processed successfully");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };
        // 模拟支付处理任务,该任务会打印处理信息并暂停2秒模拟业务操作,执行完成后返回支付完成的结果
        Callable<String> paymentTask = () -> {
            System.out.println("Processing payment...");
            Thread.sleep(2000);
            return "Payment completed";
        };
        // 将订单处理任务提交到orderPool线程池进行处理
        AdvancedThreadPoolUtil.execute("orderPool", orderTask);
        // 将支付处理任务提交到paymentPool线程池进行处理,并通过Future获取任务执行结果
        try {
            Future<String> future = AdvancedThreadPoolUtil.submit("paymentPool", paymentTask);
            System.out.println(future.get());
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        // 获取orderPool线程池的活跃线程数,并打印输出
        int activeCount = AdvancedThreadPoolUtil.getActiveCount("orderPool");
        System.out.println("Active threads in orderPool: " + activeCount);
        // 动态调整paymentPool线程池的最大线程数为15,以应对可能的业务流量变化
        AdvancedThreadPoolUtil.setMaximumPoolSize("paymentPool", 15);
        // 关闭orderPool线程池,释放相关资源
        AdvancedThreadPoolUtil.shutdown("orderPool");
    }
}

在这个业务实例中,我们通过创建不同类型的任务,并将其提交到对应的线程池,展示了线程池工具类的基本使用方法。同时,获取线程池状态、动态调整参数以及关闭线程池等操作,也体现了工具类在实际业务中的灵活性和实用性。通过合理配置和使用线程池,可以有效提升电商系统在处理订单和支付等业务时的效率和稳定性。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表