Java线程池详解

张裕  金牌会员 | 2024-8-20 16:32:41 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 571|帖子 571|积分 1713

Java线程池详解

线程池解释

线程池采用了池化思想,能够有效的管理线程的生命周期,减少了每次获取资源的斲丧,提高了资源的利用率。雷同池化实现还有数据库连接池、HTTP连接池等
利益


  • 减少了线程创建和销毁的开销
  • 提高了响应速率
  • 使得线程更加方便管理
常见使用场景


  • 量大处置惩罚时间较短的任务:有效利用线程池减少线程创建销毁的斲丧
  • 需要限制线程数目时:线程越多对资源的斲丧越大,线程池可以设置最大线程数进行限制
  • 异步执行一批不需要立即反馈结果的任务:异步执行任务,减少系统响应时间
线程池的引入:Executor框架

Executor框架为Java 5 引入,将传统线程的操控方法进行优化升级,使其针对不同 场景更加的机动、管理更加的方便,其核心jar包为java.util.concurrent,简称JUC。别的,很重要的一点,该框架还避免了 this逃逸题目。
this逃逸:指在构造函数返回之前,其他线程持有了该对象的引用,此时引用该对象调用其方法时,可能会出现欠好排查的异常。
Executor框架主要包罗三个部分


  • 任务:Runnabale/Callable,可以被 ThreadPoolExecutor 或 ScheduledThreadPoolExecutor(继承ThreadPoolExecutor) 执行
  • 执行:通过实现Executor接口的子接口ExecutorService去构造相对来说比较完整的线程池执行系统
  • 返回值:线程池的优势之一,通过实现Futrure接口的FutureTask 类将异步执行的结果获取到
  • 主线程创建 Runnable 或者 Callable 的任务对象,然后把 实现的 Runnbale 或者 Callable 交给 ExecutorService 执行:ExecutorService.execute(Runnable command) 或者 把 Runnable对象或者 Callable 对象提交给 ExecutorService 执行(ExecutorService.submit(Runnable command))
  • 如果执行 ExecutorService.submit(),ExecutorService 返回一个实现了 Future 接口的对象(submit() 会返回一个 FuturesTask对象,FutureTask 实现了 Runnable,可以创建FutureTask,然后直接交给 ExecutorService执行;execute 则会把异常打印出来)
  • 末了,主线程执行 FuturesTask.get() 方法等待任务执行完成。也可以通过 FutureTask.cancel(boolean mayInterruptIfRunning) 来取消此任务执行。
以ThreadPoolExecutor为例,ThreadPoolExecutor继承了AbstractExecutorService(抽象函数)的submit方法,而且实现了AbstractExecutorService来自Executor接口的execute方法,因此在调用线程池的submit方法时就会通过ThreadPoolExecutor的execute将任务(Runnabale/Callable为核心的RunnableFuture对象)加到工作队列中(addWorker方法实现),返回值则通过RunnableFuture对象的情势返回。
简单来说就是主线程将Runnabale/Callable对象通过submit方法提交给线程池,线程池通过内部调度按照不同的策略执行多线程任务,然后通过返回的Futrure对象的get方法取出执行结果。
ThreadPoolExecutor 类

线程池实现类 ThreadPoolExecutor 是 Executor 框架最核心的类
主线程提交任务后

  • 第一步,判断核心线程池线程数是否已满,若未满则创建线程,若已满则进入第二步
  • 第二步,判断等待队列是否已满,若未满则参加队列,若已满则进入第三步
  • 第三步,判断最大线程数是否已满,若未满则创建线程,若已满则根据设定的拒绝策略处置惩罚
参数介绍:


  • corePoolSize:核心线程数,能第一时间处置惩罚的线程数
  • maximumPoolSize:最大线程数,当核心线程池以及队列都满了的时候,线程池就会扩充到最大线程数
  • workQueue: 当核心线程池已满时,队列可以用来暂存后边进来的任务
  • keepAliveTime:线程数目大于核心线程数目时,线程闲置时间凌驾此值的线程会被回收掉,直至缩到核心线程数
  • unit:keepAliveTime 参数的时间单位
  • threadFactory:线程工厂,executor 创建线程时用到
  • handler:拒绝策略线程池已达到最大线程数,此时队列也满了,再有任务进来就会触发拒绝策略
拒绝策略:


  • AbortPolicy:拒绝任务并抛异常RejectedExecutionException
  • CallerRunsPolicy:直接在调用线程中执行任务,影响性能
  • DiscardPolicy:拒绝任务,不报异常,不做任何处置惩罚
  • DiscradOldestPolicy:拒绝掉最早的任务,执行最新的
线程池干系的内容有很多,该文章重在介绍,若要穷究其中的某个元素,可以通过参考源码的方式,这样可以最直观的看到内部构成以及各个元素之间怎样合作解决线程池的实现题目。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

张裕

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表