怎么创建线程池

  1. 方法一:通过构造方法

  2. 方法二:通过Executor框架的工具类Executors来实现三种类型的线程池

    • FixedThreadPool:该方法返回一个固定数量的线程池。
    • SingleThreadPool:该法方法返回一个只有一个线程的线程池。
    • CachedThreadPool:该方法返回一个可根据需要创建新线程的线程池。

为什么要创建线程池呢

  1. 降低资源消耗,通过重复利用已经创建的线程,来降低线程创建和销毁时的消耗。

  2. 提高响应速度,当任务到达时,可以不用等待线程的创建的时间而直接执行。

  3. 提高线程的可管理性,线程是一种稀缺资源,不能无限制创建得节制,否则就降低稳定性。先用线程池,就可以对线程进行统一的调配,管制和监控。


线程池的处理流程

理解这个流程很简单,大家可以想象一下自己住在大学宿舍(带独卫的) 当一个任务到来时(当你想上厕所时)

  • 第一步肯定要先看看核心线程池满了没有,没有满就添加到核心线程池中。

(首先你肯定先看自己宿舍的厕所有没有人用,要是没人用呢肯定不多逼逼,直接解决。)

  • 第二步,如果核心线程池满了,呢就看看工作队列有没有满,没满则加入。

(宿舍厕所被舍友用着,也没办法,你只能排队等着对吧,巧就巧在你的其它舍友也在排队。你等不了。就只能想其它办法。)

  • 第三步,如果工作队列满了,就看看线程池有没有满,没满则加入。

(这时你最佳的解决办法是看看宿舍楼道的公共厕所有没有位置,有位置就解决了。)

  • 第四步,如果线程池也满了,呢就会执行相应的处理策略。

(如果你在第三步都没有解决掉上厕所这个问题,你的朋友可能就会给你出出主意)

在线程池处于饱和状态时,系统默认提供了以下4中策略:

  • AbortPolicy:直接抛出异常。

(你上不了厕所,你别说抛异常,就是抛啥也不太好使呀。)

  • CallerRunsPolicy:只用调用者所在线程来运行任务。

(对不起,这个我不知到怎么来比喻,原谅我文采不够。)

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

(也就是说,你可以回宿舍,给舍友做个舔狗,让排在第一个的舍友别上厕所,把位置让给你。)

  • DiscardPolicy:不处理,丢弃掉。(重要

(对不起,我真的不信你能把这个感觉憋回去。)

当然,你也可以根据需要来实现RejectedExecutionHandler接口自定义策略。(觉得朋友的解决方案不靠谱,你可以自己想方案来解决)


参考《Java并发编程的艺术》