• 线程池知识点补充与总结


    前言

    最近连续三天我们都在探讨线程池相关知识,因为过程讲的比较细,所以花的时间也比较久,不过昨天分享完成后,这块的内容也就基本结束了,今天我们就花一点时间做一个简单的总结,然后在总结之外,我们再把之前遗漏的知识点补充下。好了,话不多说,让我们直接开始吧!

    线程池

    今天的内容主要包括两个方面,一个就是总结,另一个就是查漏补缺,我们先说线程池的总结。

    总结

    关于总结的内容,我画了一个脑图(持续补充),所以总结就主要围绕这个脑图展开,这个脑图各位小伙伴可以在公众号聊天窗口输入【线程池】获取:

    因为是总结,所以这一款的内容就不拖沓,只说知识点,想了解更详细的内容可以翻看最忌三天的推送内容。

    构造参数

    线程池有7个构造参数:

    • corePoolSize:核心线程数
    • maximumPoolSize:最大线程数
    • keepAliveTime:线程存活时间
    • TimUnit:线程存活时间的时间单位
    • workQueue:工作队列
    • ThreadFactory:线程工厂
    • RejectedExecutionHandler:拒绝策略处理器
    构造方法

    线程池有四个构造方法:

    • 基本构造方法:前五个参数(那天我说就三个,我是没算存活时间和存活时间的时间单位)
    • 工厂构造方法:前五个参数 + 线程工厂
    • 策略构造方法:前五个参数 + 拒绝策略处理器
    • 全套构造方法:所有参数都有
    常用方法
    • execute:执行多线程任务,没有返回值
    • submit:执行多线程人,有返回值的,父类方法
    • shutdown:关闭线程池
    其他方法
    • prestartCoreThread:预启动一个核心线程,如果核心线程都已经启动就没啥用了
    • prestartAllCoreThreads:预启动所有核心线程,如果核心线程都启动这个方法也一样没有用
    • shutdownNow:立即关闭线程池,关于它和shutdown的区别,我们后面补充说明
    • isShutdown:线程池是否已关闭,如果执行过shutdown或者shutdwonNow,则该方法值为true
    • isTerminating:线程池是否正在停止,执行过关闭方法后,但线程池未完全停止,该方法值为true
    • isTerminated:线程池彻底关闭后该方法值为true
    • purge:移除工作队列中所以被取消的任务
    • remove:移除工作队列中的任务
    核心知识点
    • 线程池能够处理的最大任务数 = corePoolSize + maximumPoolSize + workQueue
    • 向已经达到最大任务处理数线程池提交新的任务时,会触发RejectedExecutionHandlerrejectedExecution方法
    • RejectedExecutionHandlerrejectedExecution方法如果抛出RejectedExecutionException会导致核心线程阻塞
    • 如果不指定RejectedExecutionHandler,系统会指定默认的处理器AbortPolicy,默认处理器会直接抛出RejectedExecutionException
    • 线程池在创建后是没有线程的,线程是在execute方法执行后才创建的
    • 可以通过prestartCoreThread或者prestartAllCoreThreads方法来初始化线程池,也就就是预创建核心线程
    • 线程池使用完成后必须关闭,否则会阻塞后续操作
    • 在核心线程没有完全启动完,每次execute都会创建新的线程
    • 线程池最大线程数只能大于等于核心线程数
    • 当任务数大于核心线程数+工作队列大小时,若最大线程数大于核心线程数,则会继续创建线程,直到线程数达到最大线程数
    • 线程存活时间只对核心线程之外的线程资源起作用,它在工作队列为空时起作用,延缓核心线程之外的线程资源的销毁
    • 线程池关闭后便再无法继续接受任务,如果关闭后继续执行excute方法会调用rejectedExecution方法

    补充知识

    shutdownshutdownNow

    shutdown执行后会等待所有已经提交的线程执行完成,执行之后,只是不能再接受新的任务,shutdwonNow会尝试关闭所有正在执行的任务,同时会取消正在等待的任务,会返回未执行完成的任务。

    下面是他们的内部实现:

    prestartCoreThreadprestartAllCoreThreads

    我们前面说了,正常情况下,线程启动是在execute方法或者sumbit方法执行的时候启动的,但是我们也可以提前启动核心线程池中线程。

    prestartCoreThread是预启动一个核心线程,当然前提条件是核心线程数未达到核心线程数上线,prestartAllCoreThreads是启动所有的核心线程,前提条件是一样的。

    其他补充内容

    其实线程池这块至少还有三块内容需要补充,一个是工作队列,一个是拒绝策略器,另一个就是系统常用的线程池的实现机制,但是我暂时不打算分享了,这块的内容看着不多,但是如果真要分享的话,至少需要分三次才能彻底搞完;

    另外一个考虑的是,不能我把什么都讲完,要给大家留一点内容供大家自学;

    最后一个原因是,最近天天都是线程池,有点上头,稍事休息下,毕竟周末也不能太卷了

    总结

    其实今天通篇就是在总结,所以总结的话就没必要多说了,但是还是想从个人学习经验这块多叨叨两句。

    学习这件事最重要的还是要主动,要多动手。对我来说,我之前对多线程的认识仅仅是停留在会用,只知道一些常用的方法,但是对于它内部的原理和实现机制,一直是不求甚解的,但是呢,通过最近这三四天,我现在已经对线程池有了更系统的认知和了解,而且也更清楚线程池实际使用的潜在问题,以及如何避免这些问题,这就是我学习的意义。

    当然更深远的意义是结合自己之前遇到的一些线上问题,我发现原来如果我能早点知道这些知识,那我可以少走很多弯路,这大概就是成长吧——技术有了积累,眼界得到开阔,未来才能走更远……

    好了,最后希望所有小伙伴都能找到适合自己的学习之路,能够在自己的努力下,得到自己期待的东西……周末快乐鸭!

  • 相关阅读:
    lamp一键安装
    mysql忘记密码
    lamp搭建
    进程与线程的一个简单解释
    使用jmeter进行api接口压力测试(转自某位大佬,感谢)
    cookie,session的区别
    Pycharm2019最新激活注册码(亲测有效)
    安装jmeter
    php环境搭建(需编译安装)
    (转载某位大神的,谢谢啦)listener.ora、tnsnames.ora和sqlnet.ora这3个文件的关系和作用
  • 原文地址:https://www.cnblogs.com/caoleiCoding/p/15024208.html
Copyright © 2020-2023  润新知