ThreadPoolExecutor运行机制

简介: <p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px"> 最近发现几起对ThreadPoolExecutor的误用,其中包括自己,发现都是因为没有仔细看注释和内部运转机制,想当然的揣测参数导致,先看一下新建一个ThreadPoolExecutor的构建参数:</p> <p s

最近发现几起对ThreadPoolExecutor的误用,其中包括自己,发现都是因为没有仔细看注释和内部运转机制,想当然的揣测参数导致,先看一下新建一个ThreadPoolExecutor的构建参数:

[java]  view plain  copy
  1. public ThreadPoolExecutor(int corePoolSize,  
  2.                           int maximumPoolSize,  
  3.                           long keepAliveTime,  
  4.                           TimeUnit unit,  
  5.                           BlockingQueue<Runnable> workQueue,  
  6.                           ThreadFactory threadFactory,  
  7.                           RejectedExecutionHandler handler)  

看这个参数很容易让人以为是线程池里保持corePoolSize个线程,如果不够用,就加线程入池直至maximumPoolSize大小,如果还不够就往workQueue里加,如果workQueue也不够就用RejectedExecutionHandler来做拒绝处理。

但实际情况不是这样,具体流程如下:

1)当池子大小小于corePoolSize就新建线程,并处理请求

2)当池子大小等于corePoolSize,把请求放入workQueue中,池子里的空闲线程就去从workQueue中取任务并处理

3)当workQueue放不下新入的任务时,新建线程入池,并处理请求,如果池子大小撑到了maximumPoolSize就用RejectedExecutionHandler来做拒绝处理

4)另外,当池子的线程数大于corePoolSize的时候,多余的线程会等待keepAliveTime长的时间,如果无请求可处理就自行销毁

内部结构如下所示:

从中可以发现ThreadPoolExecutor就是依靠BlockingQueue的阻塞机制来维持线程池,当池子里的线程无事可干的时候就通过workQueue.take()阻塞住。

其实可以通过Executes来学学几种特殊的ThreadPoolExecutor是如何构建的。

[java]  view plain  copy
  1. public static ExecutorService newFixedThreadPool(int nThreads) {  
  2.     return new ThreadPoolExecutor(nThreads, nThreads,  
  3.                                   0L, TimeUnit.MILLISECONDS,  
  4.                                   new LinkedBlockingQueue<Runnable>());  
  5. }  

newFixedThreadPool就是一个固定大小的ThreadPool

[java]  view plain  copy
  1. public static ExecutorService newCachedThreadPool() {  
  2.     return new ThreadPoolExecutor(0, Integer.MAX_VALUE,  
  3.                                   60L, TimeUnit.SECONDS,  
  4.                                   new SynchronousQueue<Runnable>());  
  5. }  

newCachedThreadPool比较适合没有固定大小并且比较快速就能完成的小任务,没必要维持一个Pool,这比直接new Thread来处理的好处是能在60秒内重用已创建的线程。

其他类型的ThreadPool看看构建参数再结合上面所说的特性就大致知道它的特性

目录
相关文章
|
4月前
|
并行计算 算法 Java
Java线程池——Executor框架
Executor 框架是 Java5 之后引进的,在 Java 5 之后,通过 Executor 来启动线程比使用 Thread 的 start 方法更好,除了更易管理,效率更好(用线程池实现,节约开销)。 Executor 框架不仅包括了线程池的管理,还提供了线程工厂、队列以及拒绝策略等,Executor 框架让并发编程变得更加简单。
|
6月前
|
Java
异步编程 - 03 线程池ThreadPoolExecutor原理剖析&源码详解1
异步编程 - 03 线程池ThreadPoolExecutor原理剖析&源码详解
19 0
|
6月前
|
安全 Java
异步编程 - 03 线程池ThreadPoolExecutor原理剖析&源码详解2
异步编程 - 03 线程池ThreadPoolExecutor原理剖析&源码详解2
35 0
|
9月前
|
存储 Java C++
ThreadPoolExecutor 线程池执行流程及核心源码分析
ThreadPoolExecutor 线程池执行流程及核心源码分析
64 0
|
11月前
|
监控 安全 Java
[并发编程] - Executor框架#ThreadPoolExecutor源码解读01
[并发编程] - Executor框架#ThreadPoolExecutor源码解读01
69 0
|
11月前
|
Java
[并发编程] - Executor框架#ThreadPoolExecutor源码解读03
[并发编程] - Executor框架#ThreadPoolExecutor源码解读03
44 0
|
11月前
|
存储 监控 Java
[并发编程] - Executor框架#ThreadPoolExecutor源码解读02
[并发编程] - Executor框架#ThreadPoolExecutor源码解读02
89 0
|
11月前
|
存储 缓存 Java
【并发编程】线程池及Executor框架
【并发编程】线程池及Executor框架
|
12月前
|
缓存 Java 调度
JUC系列学习(一):线程池Executor框架及其实现ThreadPoolExecutor
`Executor` 框架将任务的提交与任务的执行**解耦**了。
|
Java Spring
线程池:第四章:ThreadPoolTaskExecutor和ThreadPoolExecutor有何区别?
线程池:第四章:ThreadPoolTaskExecutor和ThreadPoolExecutor有何区别?
151 0
线程池:第四章:ThreadPoolTaskExecutor和ThreadPoolExecutor有何区别?