首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

线程池工作实现原理

一个线程提交到线程池的处理流程如下图

1)初始化线程池,线程池初始化时并没有创建corePoolSize数目的核心线程,而是惰性加载的方式。等有任务后才创建核心线程。

2)如果线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的核心线程来处理被添加的任务。

3)如果线程池中的数量大于等于corePoolSize,但是缓冲队列workQueue未满,那么任务被放入缓冲队列。

4)如果线程池中的数量大于等于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的非核心线程来处理被添加的任务。

5)如果此时线程池中的数量大于等于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。

import java.util.concurrent.*;

public class ThreadPoolExecutorDemo { public static void main(String[] args) { // 创建一个线程池对象 ThreadPoolExecutor executor = new ThreadPoolExecutor( 2, 5, 10, TimeUnit.SECONDS, new ArrayBlockingQueue(5), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());

// 提交多个任务到线程池中 for (int i = 1; i executor.execute(() -> { try { Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + " is running"); } catch (InterruptedException e) { e.printStackTrace(); } }); }

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

线程池四种拒绝策略

1.AbortPolicy

特点:不执行此任务,而且直接抛出一个运行时异常。

应用场景:适用于对任务丢失敏感的场景,当线程池无法接受新任务时,希望立即知道并处理该异常。

2.DiscardPolicy

特点:新任务被提交后直接被丢弃掉,并且不会抛出异常,无法感知到这个任务会被丢弃,可能造成数据丢失。

使用场景:适用于对任务丢失不敏感的场景,当线程池无法接受新任务时,简单地丢弃被拒绝的任务。

3.DiscardOldestPolicy

特点:会丢弃任务队列中的头结点,通常是存活时间最长并且未被处理的任务。

使用场景:适用于对新任务优先级较高的场景,当线程池无法接受新任务时,会丢弃一些等待时间较长的旧任务,以便接受新任务。

4.CallerRunsPolicy

特点:当有新任务提交后,如果线程池没被关闭且没有能力执行,则把这个任务交于提交任务的线程执行,也就是谁提交任务,谁就负责执行任务。不会抛出异常。

使用场景:适用于希望调用者自己处理被拒绝的任务的场景,通常是由调用者自身的线程来执行被拒绝的任务。

优点:

1)新提交的任务不会被丢弃,这不会造成业务损失。

2)此策略提供简单的反馈控制机制,能够减缓新任务的提交速度。提交任务的线程需要负责执行任务,而执行任务又是比较耗时的,在这段期间,提交任务的线程被占用,也就不会再提交新的任务,减缓了任务提交的速度,相当于是一个负反馈。在此期间,线程池中的线程也可以充分利用这段时间来执行掉一部分任务,腾出一定的空间,相当于是给了线程池一定的缓冲期。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/O2EsAYp27xZLJ6VzLd4Z6QhQ0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券