Java线程池 Executor框架概述

2021年11月24日 阅读数:4
这篇文章主要向大家介绍Java线程池 Executor框架概述,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

线程池的意义

  1. 循环利用线程资源,避免重复建立和销毁线程
  2. 线程池的任务是异步执行的,只要提交完成就能快速返回,能够提升应用响应性
  3. Java线程池还有一个很重要的意义:Java线程池就是JDK 5 推出的Executor框架,在此以前Java线程既是工做任务又是执行机制,而Executor框架把工做任务与执行机制分离开来:工做任务包括Runnable接口和Callable接口,而执行机制由Executor接口提供。

Executor 类继承体系

Executor框架由三个部分组成

  1. 工做任务:Runnable/Callable 接口
    • 工做任务就是Runnable/Callable接口的实现,能够被线程池执行
  2. 执行机制:Executor接口、ExecutorService接口、ScheduledExecutorService接口
    • ThreadPoolExecutor 是最核心的线程池实现,用来执行被提交的任务
    • ScheduledThreadPoolExecutor 是任务调度的线程池实现,能够在给定的延迟后运行命令,或者按期执行命令(它比Timer更灵活)
    • ForkJoinPool是一个并发执行框架
  3. 异步计算的结果:Future接口
    • 实现Future接口的FutureTask类,表明异步计算的结果

线程池的实现原理

线程池的5个重要参数(需记牢):html

  • workQueue:工做(任务)队列
  • corePoolSize、maximumPoolSize:最小最大线程数
  • keepAliveTime:线程存活时间
  • threadFactory:线程工厂
  • handler:拒绝策略

  1. 若是运行的线程数少于corePoolSize,建立新线程来处理任务(注意,这一步须要获取全局锁)
  2. 不然,说明线程数大于corePoolSize,将任务插入BlockingQueue
  3. 若是插入任务失败(队列已满),且运行的线程数少于maximumPoolSize,建立新线程来处理任务(注意,这一步须要获取全局锁)
  4. 不然,说明线程数大于maximumPoolSize,执行拒绝策略

ThreadPoolExecutor 采起上述设计思路,是为了尽量地避免获取全局锁,在完成预热以后(当前运行的线程数大于等于corePoolSize),则几乎全部的调用都是执行步骤2,而步骤2不须要获取全局锁并发

关闭线程池

能够调用shutdown()或shutdownNow()来关闭线程池,其中原理是遍历全部工做线程,而后逐个调用线程的interrupt()来进行中断。可是它们存在必定的区别,shutdownNow首先将线程池的状态设置成STOP,而后尝试中止全部的正在执行或暂停任务的线程,并返回等待执行任务的列表,而shutdown只是将线程池的状态设置成SHUTDOWN状态,而后中断全部没有正在执行任务的线程。框架

只要调用了这两个关闭方法中的任意一个,isShutdown()就会返回true。当全部的任务都关闭后,才表示线程池关闭成功,这时调用isTerminaed()会返回true。至于调用哪种方法来关闭线程池,应该由线程池的任务特性决定,一般调用shutdown方法来关闭线程池,若是任务不必定要执行完,则能够调用shutdownNow方法异步

原文出处:https://www.cnblogs.com/pomer-huang/p/Java-Executor.htmlspa