线程池,及7大参数,4大拒绝策略详解

本文详细介绍了线程池的概念、工作原理,重点讲解了corePoolSize、maximumPoolSize、workQueue和handler等核心参数,以及四种常见的拒绝策略,包括默认的AbortPolicy和自定义策略。

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

线程池,及7大参数,4大拒绝策略详解

线程池是什么

​ 池化技术我们经常见,比如学习spring JDBC要学习数据库连接池,学习Http网络协议的时候要引入http连接池.同样的,多线程也有与之对应的线程池.池化技术的思想主要是为了减少每次获取,对系统资源的消耗提高资源的利用率.

  • 我们知道在面向对象编程中,创建和销毁对象是很费时间的,因为线程其实也是一个对象,创建一个对象,需要经过类加载过程,销毁一个对象,需要走GC垃圾回收流程,都是需要资源开销的。

  • 重复利用.线程用完,再放回池子,可以达到重复利用的效果,节省资源。

  • 提高响应速度. 如果任务到达了,相对于从线程池拿线程,重新去创建一条线程执行,速度肯定慢很多。

  • 提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗

系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调

优和监控。

  • 附加功能:提供定时执行、定期执行、单线程、并发数控制等功能。

线程池的工作流程

  1. 线程池刚创建时,里面没有一个线程。任务队列是作为参数传进来的。不过,就算队列里面有任务,线程池也不会马上执行它们。
  2. 当调用 execute() 方法添加一个任务时,线程池会做如下判断:
  • 如果正在运行的线程数量小于 corePoolSize,那么马上创建线程运行这个任务;

  • 如果正在运行的线程数量大于或等于 corePoolSize,那么将这个任务放入队列;

  • 如果这时候队列满了,而且正在运行的线程数量小于 maximumPoolSize,那么还

​ 是要创建非核心线程立刻运行这个任务;

  • 如果队列满了,而且正在运行的线程数量大于或等于 maximumPoolSize,那么线

程池会根据拒绝策略来对应处理。

在这里插入图片描述

  1. 当一个线程完成任务时,它会从队列中取下一个任务来执行。

  2. 当一个线程无事可做,超过一定的时间(keepAliveTime)时,线程池会判断,

    如果当前运行的线程数大于 corePoolSize,那么这个线程就被停掉。所以线程池

    的所有任务完成后,它最终会收缩到 corePoolSize 的大小。

线程池七大参数

在这里插入图片描述

​ 线程池有七大参数,需要重点关注 corePoolSize 、 maximumPoolSize 、

workQueue 、 handler 这四个。

  • corePoolSize 表示线程池的核心线程数,即在池中一直保持的线程数。当有新任务提交时,如果当前池中的线程数小于 corePoolSize,则会创建一个新的线程来处理该任务。如果线程数已经达到 corePoolSize,则新的任务会被放入到线程池的工作队列中。

  • maximumPoolSize 表示线程池允许的最大线程数,包括核心线程数和非核心线程数。当线程池中的工作队列(通常是一个阻塞队列,比如 BlockingQueue)已满,并且线程数小于 maximumPoolSize 时,线程池会创建新的非核心线程来处理任务。

    • 这样的设计允许线程池在处理大量任务时动态地增加线程数量,以提高并发性能。当任务数很大时,线程池可以通过创建额外的线程来处理任务,而当任务数减少时,线程池可以通过关闭多余的线程来释放资源
  • keepAliveTime 是用于设置非核心线程的闲置时间的参数。对于线程池中的非核心线程(即线程池的最大线程数超过核心线程数的部分),如果它在闲置状态超过了 keepAliveTime 设置的时间,那么这个线程将被终止并从线程池中移除。

  • unit:线程池中非核心线程保持存活的时间的单位

TimeUnit.DAYS; 天

TimeUnit.HOURS; 小时

TimeUnit.MINUTES; 分钟

TimeUnit.SECONDS; 秒

TimeUnit.MILLISECONDS; 毫秒

TimeUnit.MICROSECONDS; 微秒

TimeUnit.NANOSECONDS; 纳秒

  • workQueue(等待队列):线程池等待队列,维护着等待执行的 Runnable 对象。当运行当线程数=

    corePoolSize时,新的任务会被添加到 workQueue 中,如果 workQueue 也满了则

    尝试用非核心线程执行任务,等待队列应该尽量用有界的。

  • threadFactory: 创建一个新线程时使用的工厂,可以用来设定线程名、是否为daemon线程等等。

  • handler: corePoolSize 、 workQueue 、 maximumPoolSize 都不可用的时候执行的饱和策

线程池的拒绝策略

  • AbortPolicy(默认策略):当任务无法被提交给线程池时,会抛出RejectedExecutionException异常。

  • CallerRunsPolicy:当任务无法被提交给线程池时,会由提交任务的线程来执行该任务。这种策略可以降低任务的提交速度,但可以保证任务的执行。

  • DiscardOldestPolicy: DiscardOldestPolicy 会丢弃队列中等待时间最长的任务,然后尝试再次提交被拒绝的任务。

  • DiscardPolicy:当任务无法被提交给线程池时,会默默地丢弃该任务,不会抛出异常也不会执行任务。这种策略会导致任务的丢失,不推荐在生产环境中使用。

  • **自定义拒绝策略:**实现 RejectedExecutionHandler 接口,自定义拒绝策略

public class MyCustomPolicy implements RejectedExecutionHandler {
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        // 自定义处理逻辑
        System.out.println("自定义拒绝策略:" + r.toString());
    }
}

然后将这个自定义策略设置给线程池:

executor.setRejectedExecutionHandler(new MyCustomPolicy());
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值