5
Java开发的同学肯定使用过多线程,使用多线程那就肯定会用到线程池。而且个人认为线程池也是各大互联网公司在面试的时候必问的一个知识点。因此作为开发人员,必须了解线程池的原理以及具体参数的含义。

首先我们来了解下线程池的基本原理
图片描述

  1. 第一步便是我们将我们的任务提交给线程池
  2. 如果线程池中线程数小于核心线程数,则创建一个新的线程来执行该任务。否则进入步骤3
  3. 提交任务时,线程池中的空闲的线程数为0并且线程数等于核心线程数,则观察线程池中的任务队列是否已满,如果未满则将任务添加到任务队列,否则进入步骤4
  4. 如果最大线程数大于核心线程数,并且总线程数小于最大线程数,则创建一个新的线程来执行该任务。否则进入步骤5
  5. 当任务队列已满时,就执行拒绝策略(后续详解拒绝策略)

在大致了解了线程池的基本工作原理之后,我们再细看下线程池核心类ThreadPoolExecutor

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
                              //省略具体的代码内容
    }

参数说明

参数 说明
corePoolSize 核心线程数
maximumPoolSize 最大线程数,一般大于等于核心线程数
keepAliveTime 线程存活时间(针对最大线程数大于核心线程数时,非核心线程)
unit 存活时间单位,和线程存活时间配套使用
workQueue 任务队列
threadFactory 创建线程的工程
handler 拒绝策略

拒绝策略有以下几种

拒绝策略 说明
AbortPolicy 为java线程池默认的阻塞策略,不执行此任务,而且直接抛出一个运行时异常。
DiscardOldestPolicy 丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
DiscardPolicy 也是丢弃任务,但是不抛出异常
CallerRunsPolicy 由调度线程处理该任务

国子监阿创
131 声望8 粉丝

任何一个傻瓜都能写出计算机能理解的程序,而优秀的程序员却能写出别人能读得懂的程序。—— Martin Fowler