线程池的介绍及运行原理

175 阅读2分钟
  1. 通过 ThreadPoolExecutor 来创建一个线程池,参数如下

    • corePoolSize(核心线程数) 默认情况下线程池是空的,只有任务提交时才会创建线程。如果当前运行的线程数少于corePoolSize,则创建新线程来处理任务;如果等于或者多于corePoolSize,则不再创建。如果调用线程池的prestartAllcoreThread方法,线程池会提前创建并启动所有的核心线程来等待任务。
    • maximumPoolSize(线程池允许创建的最大线程数) 如果任务队列满了并且线程数小于maximumPoolSize时,则线程池仍旧会创建新的线程来处理任务。
    • keepAliveTime(非核心线程闲置的超时时间) 超过这个时间则回收。如果任务很多,并且每个任务的执行事件很短,则可以调大keepAliveTime来提高线程的利用率。另外,如果设置allowCoreThreadTimeOut属性为true时,keepAliveTime也会应用到核心线程上。
    • TimeUnit(keepAliveTime参数的时间单位) 可选的单位有天(DAYS)、小时(HOURS)、分钟(MINUTES)、秒(SECONDS)、毫秒(MILLISECONDS)等。
    • workQueue(任务队列) 如果当前线程数大于corePoolSize,则将任务添加到此任务队列中。该任务队列是BlockingQueue类型的,也就是阻塞队列。
    • RejectedExecutionHandler(饱和策略) 这是当任务队列和线程池都满了时所采取的应对策略,默认是AbordPolicy,表示无法处理新任务,并抛出RejectedExecutionException异常。
  2. 线程池的处理流程

    • 如果线程池中的线程数未达到核心线程数 ,则创建核心线程处理任务。
    • 如果线程数大于或者等于核心线程数 ,则将任务加入任务队列,线程池中的空闲线程会不断地从任务队列中取出任务进行处理。
    • 如果任务队列满了 ,并且线程数没有达到最大线程数,则创建非核心线程去处理任务。
    • 如果线程数超过了最大线程数 ,则执行饱和策略。
  3. 线程池的种类

    • FixedThreadPool 一种线程数量固定的线程池,只有核心线程并且不会被回收,没有超时机制。
    • CachedThreadPool 一种线程数量不定的线程池,只有非核心线程,当线程都处于活动状态时,会创建新线程来处理新任务,否则会利用空闲的线程,超时时长为60s。
    • SingleThreadExecutor 核心线程数是固定的,非核心线程数没有限制,非核心线程闲置时立刻回收,主要用于执行定时任务和固定周期的重复任务。
    • ScheduledThreadPool 只有一个核心线程,确保所有任务在同一线程中按顺序执行。