当前位置:   article > 正文

ThreadPoolExecutor创建线程池_threadpoolexecutor 创建线程池

threadpoolexecutor 创建线程池

ThreadPoolExecutor创建线程池

一、前言

ThreadPoolExecutor是Java中用于管理线程池的类,它提供了一个灵活且可配置的线程池,可以有效地执行并管理多个任务。使用ThreadPoolExecutor可以实现线程的复用、线程池大小的控制、任务调度和异常处理等功能。

二、相关介绍

1. 构造函数定义

当使用new关键字去创建ThreadPoolExecutor类型的对象时,相关的构造函数定义如下:

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
    if (corePoolSize < 0 ||
        maximumPoolSize <= 0 ||
        maximumPoolSize < corePoolSize ||
        keepAliveTime < 0)
        throw new IllegalArgumentException();
    if (workQueue == null || threadFactory == null || handler == null)
        throw new NullPointerException();
    this.acc = System.getSecurityManager() == null ?
            null :
            AccessController.getContext();
    this.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
2. 构造函数参数解读
  • corePoolSize(核心线程数):
    • 必须大于或等于零
    • 定义线程池的基本大小,即在没有任务执行时线程池的大小。
    • 核心线程会一直存活,即使没有任务需要执行。
    • 当任务数量超过核心线程数时,线程池会创建新的线程来处理任务,直到达到最大线程数。
    • 如果调用了线程池的prestartCoreThread()方法,核心线程会提前启动。
  • maximumPoolSize(最大线程数):
    • 必须大于零,且大于或等于核心线程数
    • 定义线程池允许创建的最大线程数。
    • 当任务数量超过核心线程数时,线程池会创建新的线程来处理任务,直到达到最大线程数。
    • 如果任务数量继续增加,而最大线程数已经达到,那么新的任务会被放入等待队列中等待执行。

      什么是等待队列?

      等待队列是在线程池中用于存储无法立即执行的任务的队列。当线程池中的线程数已达到最大线程数时,新提交的任务会被放入等待队列中等待执行。等待队列可以采用不同的实现,如ArrayBlockingQueueLinkedBlockingQueueSynchronousQueue等。如果等待队列已满,并且线程池中的线程数已达到最大线程数,那么线程池会根据预定义的拒绝策略来处理新提交的任务。

  • keepAliveTime(线程空闲时间):
    • 必须大于或等于零
    • 当线程池中的线程数量超过核心线程数时,多余的空闲线程的存活时间。
    • 当线程处于空闲状态,并且空闲时间超过keepAliveTime时,线程会被终止,直到线程数量等于核心线程数。
  • unit(时间单位):
    • 用于定义keepAliveTime参数的时间单位,可以是TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)等。
  • workQueue(工作队列):
    • 必须非空
    • 用于存储待执行任务的队列。
    • 当任务数量超过核心线程数时,新的任务会被放入工作队列中等待执行。
    • 工作队列采用先进先出(FIFO)的原则,即先提交的任务先执行。
    • ThreadPoolExecutor提供了多种实现类,如ArrayBlockingQueueLinkedBlockingQueueSynchronousQueue等。
  • threadFactory(线程工厂):
    • 必须非空
    • 用于创建新线程的工厂。
    • 可以自定义线程工厂,以便为线程设置特定的属性,如名称、优先级等。
  • handler(拒绝策略):
    • 必须非空
    • 当线程池和工作队列都满了,无法执行新的任务时,拒绝策略会定义如何处理这些任务。
    • ThreadPoolExecutor提供了多种预定义的拒绝策略,如AbortPolicyCallerRunsPolicyDiscardPolicyDiscardOldestPolicy等。

      Java中的ThreadPoolExecutor类提供了哪些预定义的拒绝策略?

      1. AbortPolicy(默认):

        如果等待队列已满且线程池中的线程数已达到最大线程数,新提交的任务会立即抛出RejectedExecutionException异常,阻止任务的执行。

      2. CallerRunsPolicy

        如果等待队列已满且线程池中的线程数已达到最大线程数,新提交的任务会由调用线程直接执行,而不会启动新的线程。

      3. DiscardPolicy

        如果等待队列已满且线程池中的线程数已达到最大线程数,新提交的任务会被默默地丢弃,不会抛出异常,也不会执行。

      4. DiscardOldestPolicy

        如果等待队列已满且线程池中的线程数已达到最大线程数,新提交的任务会尝试替换等待队列中最早的任务(即队头任务),然后重新提交新任务。

三、线程池处理流程

在这里插入图片描述

四、使用示例

1. 简单使用
public static void main(String[] args) {
    // 创建ThreadPoolExecutor
    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5,
        10, 5000,
        TimeUnit.MICROSECONDS, new LinkedBlockingDeque<>(),
        Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
    // 提交任务给线程池执行
    for (int i = 0; i < 20; i++) {
        // 创建任务对象
        Runnable task = () -> System.out.println(Thread.currentThread().getName() + ":任务执行啦");
        threadPoolExecutor.execute(task);
    }
    // 关闭线程池
    threadPoolExecutor.shutdown();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

结果记录:

pool-1-thread-2:任务执行啦
pool-1-thread-3:任务执行啦
pool-1-thread-5:任务执行啦
pool-1-thread-1:任务执行啦
pool-1-thread-4:任务执行啦
pool-1-thread-5:任务执行啦
pool-1-thread-3:任务执行啦
pool-1-thread-2:任务执行啦
pool-1-thread-5:任务执行啦
pool-1-thread-4:任务执行啦
pool-1-thread-1:任务执行啦
pool-1-thread-1:任务执行啦
pool-1-thread-1:任务执行啦
pool-1-thread-1:任务执行啦
pool-1-thread-4:任务执行啦
pool-1-thread-4:任务执行啦
pool-1-thread-5:任务执行啦
pool-1-thread-2:任务执行啦
pool-1-thread-3:任务执行啦
pool-1-thread-1:任务执行啦
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
2. Spring中使用
/**
 * 线程池
 *
 * @Author: Isabener
 * @Date: 2023/5/28 11:04:58
 */
@Configuration
public class TaskPoolConfig {

    @Bean(name = "passionAsyncExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(7);
        executor.setMaxPoolSize(15);
        executor.setQueueCapacity(50);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("passion-asyns-executor-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
/**
* 注:该方法所在类需要被Spring所管理
*/
@Async("passionAsyncExecutor")
public void test() {
    //业务逻辑
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/104635
推荐阅读
相关标签
  

闽ICP备14008679号