ThreadPoolExecutor详解-FixedThreadPool

来源:互联网 发布:免费的海关数据网站 编辑:程序博客网 时间:2024/06/05 18:18

FixedThreadPool类型的线程池由Executors创建,具体的创建方法如下:

public static ExecutorService newFixedThreadPool(int nThreads) {          return new ThreadPoolExecutor(nThreads, nThreads,                                        0L, TimeUnit.MILLISECONDS,                                        new LinkedBlockingQueue<Runnable>());      }  

上述方法是只需要指定固定的线程数量即可,工厂类会根据线程数量和Executors中提供的默认线程工厂类来创建固定数量的线程。默认线程工厂类如下:
/**      * The default thread factory      */      static class DefaultThreadFactory implements ThreadFactory {          static final AtomicInteger poolNumber = new AtomicInteger(1);          final ThreadGroup group;          final AtomicInteger threadNumber = new AtomicInteger(1);          final String namePrefix;            DefaultThreadFactory() {              SecurityManager s = System.getSecurityManager();              group = (s != null)? s.getThreadGroup() :                                   Thread.currentThread().getThreadGroup();              namePrefix = "pool-" +                            poolNumber.getAndIncrement() +                           "-thread-";          }            public Thread newThread(Runnable r) {              Thread t = new Thread(group, r,                                    namePrefix + threadNumber.getAndIncrement(),                                    0);              if (t.isDaemon())                  t.setDaemon(false);              if (t.getPriority() != Thread.NORM_PRIORITY)                  t.setPriority(Thread.NORM_PRIORITY);              return t;          }      } 
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {        return new ThreadPoolExecutor(nThreads, nThreads,                                      0L, TimeUnit.MILLISECONDS,                                      new LinkedBlockingQueue<Runnable>(),                                      threadFactory);    }  
该创建方法与第一种相比多了一个ThreadFactory类,可以传入自定义线程创建工厂类,自己控制线程的创建。
public ThreadPoolExecutor(int corePoolSize,                                int maximumPoolSize,                                long keepAliveTime,                                TimeUnit unit,                                BlockingQueue<Runnable> workQueue,                                ThreadFactory threadFactory) {          this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,               threadFactory, defaultHandler);      }  

通过ThreadPoolExecutor的构造方法可以看出,工厂类传递的第一个参数和第二个参数都设置成了nThreads。即线程池的初始值和最大值都设置为了指定的线程数量。

keepAliveTime为多余的空闲线程等待新任务的最长时间,超过这个时间后多余的线程仍然没有可以执行的任务将会被终止,这里设置成0表示多余的空闲线程会被立即终止。

通过构造参数可以看出,线程池的构造参数中还传入了一个阻塞队列,该阻塞队列的作用其实就是作为一个任务的缓冲区。

现在可以分析一下该线程池的工作流程如下:

1、如果当前运行的线程数量少于corePoolSize,则创建新线程来执行任务。

2、在线程池中当前运行的线程数量等于corePoolSize,由于无法在创建新的线程进行任务处理,所以会将任务加入到阻塞队列中进行排队等候处理。

3、当线程池中的线程执行完一个任务后,就会去阻塞队列中循环获取新的任务继续执行。

所以外部线程可以一直提交任务到线程池中阻塞队列中,然后,线程池中的工作线程在获取任务进行执行,这里其实是一个典型的生产者-消费者模式。

但是外部线程提交的任务数量有限制么,这就要看传入的阻塞队列是否有容量限制,从上图可以看出是传入的一个没有指定构造参数的LinkedBlockingQueue,发现这里没有指定容量的大小,可以该队列的构造方法实现中去查看源码如下:


public LinkedBlockingQueue() {       this(Integer.MAX_VALUE);   }  
发现没有传入任务参数的时候,队列会默认创建容量大小为Integer.MAX_VALUE的阻塞队列。


原创粉丝点击