ThreadPoolExecutor详解-FixedThreadPool

来源:互联网 发布:vip视频解析源码php 编辑:程序博客网 时间:2024/06/08 10:15

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的阻塞队列。



0 0
原创粉丝点击