• 线程池工作原理及参数


    线程池

    线程池的作用

    • 降低资源的消耗
    • 提高响应速度
    • 提高线程的客观理性

    当一个新任务到达线程池时,其处理流程?

    • 1、线程池判断核心线程池的线程是否都在执行任务。

    是:进入下个流程

    否:创建一个新的工作线程来执行任务(需要加上全局锁)

    工作线程:线程池创建线程时,会将线程封装成工作线程Worker,Worker在执行完任务后,还会循环获取工作队列里的任务来执行

    • 2、线程池判断工作队列是否已满

    是:进入下个流程

    否:将新提交的任务存储在工作队列中

    • 3、线程池判断线程池的线程是否都处于工作状态

    是:交给饱和策略来处理

    AbortPolicy:直接抛出异常(默认策略)

    CallerRunsPolicy:只用调用者所在的线程来执行任务

    DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务

    DiscardPolicy:不处理,直接丢弃

    否:创建新的工作线程来执行任务(需要加上全局锁)

    介绍一下线程池的参数

    • 1、corePoolSize:线程池的基本大小

    当提交一个任务到线程池时,线程池会创建一个线程来执行任务,即是其他空闲的基本线程能够执行新的任务,也会创建这个线程,等到需要执行的任务数大于线程池的基本大小的时候就不再创建

    • 2、runnableTaskQueue:任务队列(用来保存等待执行任务的阻塞队列)

    1、ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,进入队列的元素按照FIFO排序

    2、LinkedBlockingQueue:一个基于链表的阻塞队列,元素按照FIFO排序,吞吐量通常要改于ArrayBlockingQueue,eg:Executors.newFixedThreadPool()

    3、SynchronousQueue:一个不存储元素的阻塞队列,每个插入操作必须等到另一个进程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常高于LinkedBlockingQueue。eg:Executors.newCachedThreadPool()

    4、PriorityBlockingQueue:一个具有优先级的无限阻塞队列

    • 3、maximumPoolSize:线程池最大数量

    线程允许创建的最大线程数。如果队列满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的线程执行任务。注意:如果是使用了上述的无界的任务队列,就没必要开启这个最大线程数的参数

    • 4、ThreadFactory:用于设置创建线程的工厂

    new ThreadFactoryBuilder().setNameFormat(“xxx-task–%d”).get();

    • 5、RejectedExecutionHandler:饱和策略

    AbortPolicy:直接抛出异常(默认策略)

    CallerRunsPolicy:只用调用者所在的线程来执行任务

    DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务

    DiscardPolicy:不处理,直接丢弃

    • 6、keepAliveTime:线程活动保持时间

    线程池的工作线程空闲后,可以存活的最长时间

    • 7、TimeUnit:线程活动保持时间的单位

    存活时间的单位

    如何向线程池中提交任务?

    • 1、execute()方法

    用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功。

    • 2、submit()方法

    用于提交需要返回值的任务,线程池会返回一个future对象,通过future对象可以判断任务是否执行成功,可以使用future.get()方法来获得返回值。

    如何关闭线程池?

    • shutdown

    • shutdownNow

    使用了上述两个中的任意一个,都会使得 isShutDown 返回 true。至所有任务都关闭后,表示线程池关闭成功,此时 isTerminated 会返回true

    如何合理的配置线程池?

    • 1、任务的性质

    CPU密集型任务:尽可能配置小的线程,因为是一直在执行任务,无需一直进行线程的切换

    IO密集型任务:并不是一直在执行任务,可以配置尽可能多的线程。

    混合型任务:可以拆分成一个CPU密集型的任务和一个IO密集型的任务,只要是任务的相差时间不是很长,效率肯定会比未拆分之前要高。

    • 2、任务的优先级

    PriorityBlockingQueue

    • 3、任务的执行时间

    • 4、任务的依赖性

    是否依赖其他的系统资源。eg:数据库连接

    如何对线程池进行监控?

    taskCount:线程池需要执行的任务的数量

    completedTaskCount:线程池已经完成的线程的数量,总量应小于taskCount

    largestPoolSize:线程池里曾经创建的最大线程数量,根据该值可以知道线程池之前是否满过,加入largestPoolSize等于线程池的最大大小,说明之前满过

    getPoolSize:线程池的线程数量,只要是线程池不销毁的话,线程不会自动销毁,该值只增不减

    getActiveCount:获取活动的线程数

  • 相关阅读:
    Arrow parquet types
    rsync远程同步
    127. SAP UI5 应用的全局配置(Global Configuration) 的设计和使用
    手写数字识别Mnist数据集和读取代码分享
    POJ3268最短路径题解
    【DS】初识集合框架,时间/空间复杂度的计算
    从入门到精通Ansible Playbook,一篇就够了
    VUE-CLI/VUE-ROUTER
    Unity Shader - if 和 keyword 的指令比较
    问:未来5年的IT互联网行业,就业形势会是什么样的?
  • 原文地址:https://blog.csdn.net/weixin_51019103/article/details/127908367