ThreadPoolExecutor详解-FixedThreadPool

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

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue());
    }
上述方法是只需要指定固定的线程数量即可,工厂类会根据线程数量和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(),
                                      threadFactory);
    }
该创建方法与第一种相比多了一个ThreadFactory类,可以传入自定义线程创建工厂类,自己控制线程的创建。

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue 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的阻塞队列。



你可能感兴趣的:(并发编程)