java线程池之threadPoolExecutor

本文深入探讨了Java线程池的核心组件ThreadPoolExecutor,解释了线程池的工作原理,包括线程池的构造参数如corePoolSize、maximumPoolSize、keepAliveTime、workQueue等,以及拒绝策略和线程池执行流程。文中强调了避免使用Executors创建线程池的原因,以防止资源耗尽风险。

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

一 、线程池

1.1 线程池简介:

        线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。如果某个线程在托管带啦中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙。如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值。超过最大值的线程可以排队,但他们要等到其他线程完成后才启动。
        在线程池的使用上,线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让开发者更加明确线程池的运行规则,规避资源耗尽的风险。

不使用Executors的相关说明:Executors 返回的线程池对象的弊端如下:
1)FixedThreadPool 和 SingleThreadPool:
允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。
2)CachedThreadPool 和 ScheduledThreadPool:
允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。

1.2 ThreadPoolExecutor线程及构造函数即相关参数介绍:

// Java线程池的完整构造函数
public ThreadPoolExecutor(

  int corePoolSize, // 线程池长期维持的核心线程数。

  int maximumPoolSize, // 最大线程数,包含核心线程数在内最多可创建的线程数。

  long keepAliveTime, TimeUnit unit, // 超过corePoolSize的非核心线程会被回收。

  BlockingQueue<Runnable> workQueue, // 任务阻塞队列。

  ThreadFactory threadFactory, // 新线程的生成工厂

  RejectedExecutionHandler handler);// 任务的拒绝策略,即拒绝过剩任务

    1.2.1 corePoolSize

        该线程池中核心线程数最大值 。线程池新建线程的时候,如果当前线程总数小于corePoolSize,则新建的是核心线程,如果超过corePoolSize,则新建的是非核心线程核心线程默认情况下会一直存活在线程池中,即使这个核心线程啥也不干(闲置状态)。如果指定ThreadPoolExecutor的allowCoreThreadTimeOut这个属性为true,那么核心线程如果不干活(闲置状态)的话,超过一定时间(时长下面参数决定),就会被销毁掉。
1.2.2 maximumPoolSize
        该线程池中线程总数最大值。线程总数 = 核心线程数 + 非核心线程数

1.2.3 keepAliveTime
        该线程池中非核心线程限制超时时长。一个非核心线程,如果不干活(闲置状态)的时长超过这个参数所设定的时长,就会被销毁掉,如果设置allowCoreThreadTimeOut = true,则会作用于核心线程。

1.2.4 unit
        keepAliveTime的单位,包括NANOSECONDS、MILLISECONDS、SECONDS、MICROSECONDS、MINUTES、HOURS、DAYS .  

1.2.5 workQueue
        该线程池中的任务队列:维护着等待执行的Runnable对象。当所有的核心线程都在干活时,新添加的任务会被添加到这个队列中等待处理,如果队列满了,则新建非核心线程执行任务。

1.2.6 threadFactory
        创建线程的方式,这是一个接口,你new他的时候需要实现他的Thread newThread(Runnable r)方法,一般用不上。一般都是采用Executors.defaultThreadFactory()方法返回的DefaultThreadFactory,当然也可以用其他的来设置更有意义的名称。       

1.2.7 handler
        拒绝策略。当使用有界队列,且队列任务被填满后,线程数也达到最大值时,拒绝策略开始发挥作用,ThreadPoolExecutor默认使用AbortPolicy拒绝策略。

1.3 线程池执行流程(此图来源其他技术博客,感觉很直观,借用):


释义:

1、当线程数小于 corePoolSize时,创建线程执行任务。
2、当线程数大于等于 corePoolSize并且 workQueue 没有满时,放入workQueue中
3、线程数大于等于 corePoolSize并且当 workQueue 满时,新任务新建线程运行,线程总数要小于 maximumPoolSize
4、当线程总数等于 maximumPoolSize 并且 workQueue 满了的时候执行 handler 的 rejectedExecution。也就是拒绝策略(图中的饱和策略)。

(不足之处请指明,谢谢!)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值