JDK1.8 线程池源码解析

1.线程池目的

  • 减少系统频繁创建、销毁线程带来的开销,重复利用线程。
  • 线程是稀缺资源,需要线程池科学规划线程数据量、工作队列以及拒绝策略,防止高并发引起服务器宕机。

2.线程池核心参数

核心类ThreadPoolExecutor实现了线程池。

  • corePoolSize,核心线程数,指线程池中报错的线程数,包含空闲线程。
  • maximumPoolSize,程池中允许的最大线程数。
  • ThreadFactory,线程工厂,用于创建线程的工具类。创建的线程具有相同的线程组、优先级、守护线程状态等。当线程工厂的newThread方法返回null时,线程池可能还在运行,但是并不能执行任何任务。
  • Keep-alive times,线程活跃时间,当线程数超过corePoolSize时,空闲时间超过keep-alive times的线程会被停掉。这是一种减负的机制,释放那些空闲的线程资源。若线程池活跃起来,又会重新创建新的线程。当然allowCoreThreadTimeOut方法可以应用超时策略。
  • unit:参数中的时间单位。
  • BlockingQueue,工作队列,用于暂存提交的请求。
线程池原理流程图.png

当任务提交给线程池,判断可运行的线程数是否达到corePoolSize,未达到,则创建新的线程处理请求,即使当前线程空闲。如果当前线程数多余corePoolSize,小于maximumPoolSize,这是要看工作队列负荷,如果工作队列已满,则创建新的线程处理请求,反之,则加入工作队列。当corePoolSize和maximumPoolSize相等,创建的是固定数量线程池。corePoolSize和maximumPoolSize在构造方法中创建,也可以通过set方法修改。

默认的,请求达到是才创建corePoolSize的请求。也可以通过重写prestartCoreThread或者prestartAllCoreThreads方法,预先创建corePoolSize的线程。

另外,加入工作队列有三种策略:
第一、直接传递,如SynchronousQueue,转手一次请求然后交给现成执行,并不会真的存储请求,当然如果没有现成立刻响应请求,则加入队列失败,因此必须创建新的现成来响应请求。这种策略要求maximumPoolSize是无界的,避免执行拒绝策略。坏处是,线程可能会无节制的增加。

第二、无界队列,如LinkedBlockingQueue,corePoolSize满了请求就会被加到无界队列,不会有超过corePoolSizede的线程数,maximumPoolSize就失效了。

第三、有界队列,如ArrayBlockingQueue,有界队列避免无节制的队列长度和无效的maximumPoolSize,Queue size和maximumPoolSize调节达到平衡。如长队列和少的线程池,降低cpu利用率、os资源利用和上下文切换开销,但是吞吐量上不去。

你可能感兴趣的:(JDK1.8 线程池源码解析)