Java中的线程池——3种常用的ThreadPoolExecutor

在Executor框架下,利用Executors的静态方法可以创建三种类型的常用线程池。他们可分别对应不同的应用场景,下面来看看这三个线程池。


1 FixedThreadPool

这个线程池可以创建固定线程数的线程池。它的构造源码如下:

[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.     }  


  • FixedThreadPool的corePoolSize和maxiumPoolSize都被设置为创建FixedThreadPool时指定的参数nThreads。
  • 0L则表示当线程池中的线程数量操作核心线程的数量时,多余的线程将被立即停止
  • 最后一个参数表示FixedThreadPool使用了*队列LinkedBlockingQueue作为线程池的做工队列,由于是*的,当线程池的线程数达到corePoolSize后,新任务将在*队列中等待,因此线程池的线程数量不会超过corePoolSize,同时maxiumPoolSize也就变成了一个无效的参数,并且运行中的线程池并不会拒绝任务
FixedThreadPool运行图如下

Java中的线程池——3种常用的ThreadPoolExecutor

2 SingleThreadExecutor


SingleThreadExecutor是使用单个worker线程的Executor。它的构造源码如下:

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

SingleThreadExecutor的corePoolSize和maxiumPoolSize都被设置1。
其他参数均与FixedThreadPool相同,其运行图如下:
Java中的线程池——3种常用的ThreadPoolExecutor

3 CachedThreadPool


CachedThreadPool是一个”无限“容量的线程池,它会根据需要创建新线程。下面是它的构造方法:

[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.     }  


CachedThreadPool的corePoolSize被设置为0,即corePool为空;maximumPoolSize被设置为Integer.MAX_VALUE,即maximum是*的。这里keepAliveTime设置为60秒,意味着空闲的线程最多可以等待任务60秒,否则将被回收。

CachedThreadPool使用没有容量的SynchronousQueue作为主线程池的工作队列,它是一个没有容量的阻塞队列。每个插入操作必须等待另一个线程的对应移除操作。这意味着,如果主线程提交任务的速度高于线程池中处理任务的速度时,CachedThreadPool会不断创建新线程。极端情况下,CachedThreadPool会因为创建过多线程而耗尽CPU资源。其运行图如下:
Java中的线程池——3种常用的ThreadPoolExecutor
1 首先执行SynchronousQueue.offer(Runnable task)。如果当前maximumPool中有空闲线程正在执行SynchronousQueue.poll(keepAliveTime,TimeUnit.NANOSECONDS),那么主线程执行的offer操作与空闲线程执行的poll操作配对成功,主线程把任务交给空闲线程执行,execute()方法执行成功,否则执行步骤2

2 当初始maximumPool为空,或者maxiumPool中当前没有空闲线程时,将没有线程执行SynchronousQueue.poll操作。这种情况下,线程池会创建一个新的线程执行任务。
3 当步骤2的线程执行完成后,将等待60秒,如果此时主线程提交了一个新任务,那么这个空闲线程将执行新任务,否则被回收。因此长时间不提交任务的CachedThreadPool不会占用系统资源

转自:http://blog.csdn.net/u010723709/article/details/50391948