• 线程池详解


    一、概念

    1、线程池管理器:用于创建并管理线程池,包括创建线程池,销毁线程池,添加新任务;

    2、工作线程:线程池中线程,可以循环的执行任务,在没有任务时处于等待状态;

    3、任务接口:每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;

    4、任务队列:用于存放没有处理的任务。提供一种缓冲机制。

    Executor是一个接口,它是Executor框架的基础,它将任务的提交与任务的执行分离开来。

    ExecutorService接口继承了Executor,在其上做了一些shutdown()、submit()的扩展,可以说是真正的线程池接口;

    AbstractExecutorService抽象类实现了ExecutorService接口中的大部分方法;

    ThreadPoolExecutor是线程池的核心实现类,用来执行被提交的任务。

    ScheduledExecutorService接口继承了ExecutorService接口,提供了带"周期执行"功能ExecutorService;

    ScheduledThreadPoolExecutor是一个实现类,可以在给定的延迟后运行命令,或者定期执行命令。ScheduledThreadPoolExecutor比Timer更灵活,功能更强大。

    Future接口和实现Future接口的FutureTask类,代表异步计算的结果。

    Runnable接口和Callable接口的实现类,都可以被ThreadPoolExecutor或Scheduled-ThreadPoolExecutor执行。

    ThreadPoolExecutor构造函数各参数含义

    1、corePoolSize

    线程池中的核心线程数,当提交一个任务时,线程池创建一个新线程执行任务,直到当前线程数等于corePoolSize;

    如果当前线程数为corePoolSize,继续提交的任务被保存到阻塞队列中,等待被执行;

    如果执行了线程池的prestartAllCoreThreads()方法,线程池会提前创建并启动所有核心线程。

    2、maximumPoolSize

    线程池中允许的最大线程数。如果当前阻塞队列满了,且继续提交任务,则创建新的线程执行任务,前提是当前线程数小于maximumPoolSize

    3、keepAliveTime

    线程空闲时的存活时间,即当线程没有任务执行时,继续存活的时间。默认情况下,该参数只在线程数大于corePoolSize时才有用

    4、TimeUnit

    keepAliveTime的时间单位

    5、workQueue

    workQueue必须是BlockingQueue阻塞队列。当线程池中的线程数超过它的corePoolSize的时候,线程会进入阻塞队列进行阻塞等待。通过workQueue,线程池实现了阻塞功能

    6、ThreadFactory

    创建线程的工厂类,不传有默认工厂Executors.defaultThreadFactory()

    Executors工具类

    ThreadPoolExecutor通常使用工厂类Executors来创建。Executors可以创建4种类型的ThreadPoolExecutor:SingleThreadExecutor、FixedThreadPool 和 CachedThreadPool,scheduledThreadPool。

    你可以自己实例化线程池,也可以用Executors 创建线程池的工厂类,常用方法如下:

    newFixedThreadPool(int nThreads) 创建一个固定大小、任务队列容量无界的线程池。核心线程数=最大线程数。

    适用于为了满足资源管理的需求,而需要限制当前线程数量的应用场景,适用于负载比较重的服务器。

    FixedThreadPool使用无界队列LinkedBlockingQueue作为线程池的工作队列(队列的容量为Integer.MAX_VALUE)。

    newCachedThreadPool() 创建的是一个大小无界的缓冲线程池。它的任务队列是一个同步队列。任务加入到池中,如果池中有空闲线程,则用空闲线程执行,如无则创建新线程执行。池中的线程空闲超过60秒,将被销毁释放。线程数随任务的多少变化。适用于执行耗时较小的异步任务。池的核心线程数=0 ,最大线程数= Integer.MAX_VALUE。

    newSingleThreadExecutor() 只有一个线程来执行无界任务队列的单一线程池。该线程池确保任务按加入的顺序一个一个依次执行。当唯一的线程因任务异常中止时,将创建一个新的线程来继续执行后续的任务。与newFixedThreadPool(1)的区别在于,单一线程池的池大小在newSingleThreadExecutor方法中硬编码,不能再改变的。

    newScheduledThreadPool(int corePoolSize) 能定时执行任务的线程池。该池的核心线程数由参数指定,最大线程数=Integer.MAX_VALUE。详情看全文的第三大点ScheduledExecutorService接口。

    FixedThreadPool和SingleThreadExecutor使用无界队列LinkedBlockingQueue作为线程池的工作队列。CachedThreadPool使用没有容量的SynchronousQueue作为线程池的工作队列,但CachedThreadPool的maximumPool是无界的。这意味着,如果主线程提交任务的速度高于maximumPool中线程处理任务的速度时,CachedThreadPool会不断创建新线程。极端情况下,CachedThreadPool会因为创建过多线程而耗尽CPU和内存资源。

    任务execute过程

    是否达到核心线程数量?没达到,创建一个工作线程来执行任务。

    工作队列是否已满?没满,则将新提交的任务存储在工作队列里。

    是否达到线程池最大数量?没达到,则创建一个新的工作线程来执行任务。

    最后,执行拒绝策略来处理这个任务。

     

  • 相关阅读:
    反序列化漏洞(2), 分析调用链, 编写POC
    WiFi 6在工业物联网应用中有哪些优势?
    【算法练习Day30】无重叠区间&& 划分字母区间&&合并区间
    挠场的科学丨一、特斯拉的特异功能与电力产业的兴起
    Leetcode 1834. Single-Threaded CPU (堆好题)
    ChatGPT科研绘图丨散点图、柱状图、小提琴图、箱型图、雷达图、玫瑰图、气泡图、森林图、三元图、三维图等各类科研图
    C++知识点总结(6):高精度乘法
    Java面试之Redis篇(offer 拿来吧你)
    windows模拟触摸
    HDLbits: Lfsr5
  • 原文地址:https://blog.csdn.net/m0_66194642/article/details/128188463