线程池的参数详细介绍 - Java

线程池(Thread Pool)是为了解决频繁创建和销毁线程所带来的性能问题而提出的一种线程管理机制。使用线程池可以重复利用已创建的线程,减少线程创建和销毁的开销,并且能有效控制系统中线程的数量,防止线程过多导致资源耗尽。

线程池在 Java 中是通过 ThreadPoolExecutor 实现的,下面我将详细介绍 ThreadPoolExecutor 的各个参数,并给出具体的示例。

ThreadPoolExecutor 构造函数

ThreadPoolExecutor 的构造函数如下:

java

ThreadPoolExecutor(int corePoolSize,
                   int maximumPoolSize,
                   long keepAliveTime,
                   TimeUnit unit,
                   BlockingQueue<Runnable> workQueue,
                   ThreadFactory threadFactory,
                   RejectedExecutionHandler handler)

各个参数的详细介绍与示例:

1. corePoolSize(核心池大小)

  • 类型int
  • 说明:线程池中始终保留的线程数,线程池中的线程数不会少于 corePoolSize,即使这些线程处于空闲状态。核心线程即使没有任务执行,也会被保持。
  • 常见应用场景:如果任务执行频繁,且负载较高,可以设置较大的核心线程数,以减少线程的创建和销毁成本。

示例

java

int corePoolSize = 4;

此示例表示线程池中的核心线程数为 4,即线程池至少会有 4 个线程在空闲时保持活跃。

2. maximumPoolSize(最大池大小)

  • 类型int
  • 说明:线程池中允许的最大线程数。当线程池中已有 corePoolSize 个线程且任务队列已满时,如果新任务提交,线程池会创建新的线程,直到线程池中的线程数达到 maximumPoolSize
  • 常见应用场景:可以根据系统资源配置该值,通常在任务量很大且负载较高时,设置较大的 maximumPoolSize

示例

java

int maximumPoolSize = 10;

此示例表示线程池中最多可以有 10 个线程。

3. keepAliveTime(空闲线程存活时间)

  • 类型long
  • 说明:当线程池中的线程数超过 corePoolSize 时,多余的线程将在空闲 keepAliveTime 时间后被销毁。如果 allowCoreThreadTimeOuttrue,则核心线程也会被超时销毁。
  • 常见应用场景:适用于长时间没有任务的情况下,线程池会销毁空闲线程,节省资源。

示例

java

long keepAliveTime = 60; // 60秒

此示例表示线程池中超过 corePoolSize 的线程在空闲 60 秒后将被销毁。

4. unit(时间单位)

  • 类型TimeUnit
  • 说明keepAliveTime 的时间单位,可以是 TimeUnit.SECONDSTimeUnit.MILLISECONDSTimeUnit.MINUTES 等。
  • 常见应用场景:根据 keepAliveTime 的值选择适合的时间单位。

示例

java

TimeUnit unit = TimeUnit.SECONDS;

此示例表示 keepAliveTime 使用秒为单位。

5. workQueue(任务队列)

  • 类型BlockingQueue<Runnable>
  • 说明:用于存放等待执行的任务。常见的实现有:LinkedBlockingQueue:无界队列,大小为 Integer.MAX_VALUE,适用于任务量无法预测的场景。ArrayBlockingQueue:有界队列,适用于任务量可以预估的场景。SynchronousQueue:没有容量的队列,每个提交的任务都必须等待一个线程来处理,适用于需要处理每个任务的特殊场景。

示例

java

BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(100);

此示例表示线程池的任务队列大小为 100,当队列满时,新的任务会被拒绝。

6. ThreadFactory

  • 类型ThreadFactory
  • 说明:线程池用来创建新线程的工厂。通过自定义 ThreadFactory,你可以设置线程的名字、优先级等属性。默认的 ThreadFactory 会创建普通的线程。
  • 常见应用场景:如果你需要给线程命名或设置特定的线程属性,可以自定义 ThreadFactory

示例

java

ThreadFactory threadFactory = new ThreadFactory() {
    private int count = 0;
    public Thread newThread(Runnable r) {
        return new Thread(r, "Custom-Thread-" + count++);
    }
};

此示例自定义了线程工厂,每个线程的名字都会被设置为 Custom-Thread-0Custom-Thread-1 等。

7. RejectedExecutionHandler

  • 类型RejectedExecutionHandler
  • 说明:当线程池无法处理新任务时,执行的策略。常见的拒绝策略有:AbortPolicy:默认策略,抛出 RejectedExecutionException。CallerRunsPolicy:由提交任务的线程执行该任务。DiscardPolicy:丢弃任务。DiscardOldestPolicy:丢弃队列中最旧的任务。

示例

java

RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();

此示例使用 CallerRunsPolicy 策略,如果线程池无法处理新任务,任务将由提交任务的线程来执行。

完整示例

java

import java.util.concurrent.*;

public class ThreadPoolExample {
    public static void main(String[] args) {
        // 创建一个线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
            4,  // corePoolSize
            10, // maximumPoolSize
            60, // keepAliveTime
            TimeUnit.SECONDS, // unit
            new LinkedBlockingQueue<>(100), // workQueue
            new ThreadFactory() {
                private int count = 0;
                @Override
                public Thread newThread(Runnable r) {
                    return new Thread(r, "Custom-Thread-" + count++);
                }
            },
            new ThreadPoolExecutor.CallerRunsPolicy() // RejectedExecutionHandler
        );

        // 提交任务到线程池
        for (int i = 0; i < 200; i++) {
            executor.submit(() -> {
                System.out.println(Thread.currentThread().getName() + " is executing the task.");
                try {
                    Thread.sleep(1000); // 模拟任务执行
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }

        // 关闭线程池
        executor.shutdown();
    }
}

解释:

  • corePoolSize 为 4,表示线程池有 4 个核心线程。
  • maximumPoolSize 为 10,最多允许 10 个线程。
  • keepAliveTime 为 60 秒,超过 4 个线程后的线程将在空闲 60 秒后被销毁。
  • workQueue 使用一个 LinkedBlockingQueue,最大容量为 100。当任务超过 100 个时,新的任务会被拒绝。
  • ThreadFactory 自定义了线程的名字为 Custom-Thread-0Custom-Thread-1 等。
  • RejectedExecutionHandler 设置为 CallerRunsPolicy,当线程池不能处理任务时,任务会由提交任务的线程来执行。

线程池工作流程

  1. 任务提交:当任务提交给线程池时,线程池会先检查是否有空闲线程。如果没有,且线程池中的线程数小于 corePoolSize,会创建新的线程执行任务。
  2. 任务排队:当线程池中的线程数已经达到 corePoolSize,但还没有达到 maximumPoolSize 时,新的任务会被放入 workQueue 队列中。
  3. 线程扩展:如果任务队列已满,且线程池中的线程数小于 maximumPoolSize,线程池会创建新的线程来处理任务。
  4. 任务拒绝:如果线程池中的线程数已达到 maximumPoolSize 且任务队列也已满,任务将根据 RejectedExecutionHandler 策略来处理。

通过合理的配置线程池参数,可以确保系统在高并发场景下平稳运行,避免线程过多导致的资源浪费或线程过少导致的任务阻塞。

Java碎碎念 文章被收录于专栏

来一杯咖啡,聊聊Java的碎碎念呀

全部评论

相关推荐

刚刷到字节跳动官方发的消息,确实被这波阵仗吓了一跳。在大家还在纠结今年行情是不是又“寒冬”的时候,字节直接甩出了史上规模最大的转正实习计划——ByteIntern。咱们直接看几个最硬的数,别被花里胡哨的宣传词绕晕了。首先是“量大”。全球招7000多人是什么概念?这几乎是把很多中型互联网公司的总人数都给招进来了。最关键的是,这次的资源分配非常精准:研发岗给了4800多个Offer,占比直接超过六成。说白了,字节今年还是要死磕技术,尤其是产品和AI领域,这对于咱们写代码的同学来说,绝对是今年最厚的一块肥肉。其次是大家最关心的“转正率”。官方直接白纸黑字写了:整体转正率超过50%。这意味着只要你进去了,不划水、正常干,每两个人里就有一个能直接拿校招Offer。对于2027届(2026年9月到2027年8月毕业)的同学来说,这不仅是实习,这简直就是通往大厂的快捷通道。不过,我也得泼盆冷水。坑位多,不代表门槛低。字节的实习面试出了名的爱考算法和工程实操,尤其是今年重点倾斜AI方向,如果你简历里有和AI相关的项目,优势还是有的。而且,转正率50%也意味着剩下那50%的人是陪跑的,进去之后的考核压力肯定不小。一句话总结:&nbsp;27届的兄弟们,别犹豫了。今年字节这是铁了心要抢提前批的人才,现在投递就是占坑。与其等到明年秋招去千军万马挤独木桥,不如现在进去先占个工位,把转正名额攥在手里。
喵_coding:别逗了 50%转正率 仔细想想 就是转正与不转正
字节7000实习来了,你...
点赞 评论 收藏
分享
评论
3
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务