前瞻

四种线程池内部构造都是来自同一个方法:

java 线程池 哪种效率最高 java线程池种类_线程池

下面分别介绍一下各个参数的含义:
corePoolSize: 线程池中所保存的核心线程数。线程池初始化启动之后,默认是空的,只有当任务来临之时,才会建立线程 处理请求。当然可以使用prestartCoreThread()方法可以使线程池初始化之后,立即建立corePoolSize个数的线程来等待任务。

maximumPoolSize: 线程池中线程数能达到的最大值。当然这个参数还与workQueue的使用策略有关,当使用无界队列(LinkedBlockQueue等)时,本参数无效。corePoolSize和maximumPoolSize的作用是控制线程池中实际运行线程的数目。例如当新的任务提交到线程池时,假设此时线程池中运行线程的数量为M,当M < corePoolSize时,会新建线程来处理任务;如果M>corePoolSize && M < maximumPoolSize时,如果是workQueue是阻塞队列时,才会创建新的线程来完成任务。如果corePoolSize == maximumPoolSize时,则意味着创建了固定大小的线程池。如果maximumPoolSize为Integer.MAX_VALUE,则可以理解为该线程池适合任意数量的并发任务。

keepAliveTime:当前线程池maximumPoolSize > corePoolSize时,终止(maximumPoolSize - corePoolSize)个空闲线程的时间。也就是说空闲状态下,(maximumPoolSize - corePoolSize)个线程存活的最长时间。

TimeUnit:keepAliveTime参数的时间单位,可以为毫秒,秒,分。。。

BlockingQueue: 任务队列,如果当前线程池中核心线程数达到了corePoolSize时,且当前所有线程都属于活动状态时,则将新的任务添加到该队列中。基本上有以下几个实现:
1) ArrayBlockQueue:基于数组结构的有界队列,此队列按FIFO(first in first out)原则对任务进行排序。如果队列已满,新的任务将会被采取拒绝策略对待。
2)LinkedBlockingQueue: 基于链表的无界队列,按FIFO原则排序。因为是无界的,所以不存在满的情况,此时拒绝策略无效
3) PriorityBlockingQueue:具有优先级的队列的有界队列,可以自定义优先级,默认为自然排序。

Handler:拒绝策略,当线程池和workQueue都满了的情况下,对新任务采取的处理策略,有四种默认实现:
1) AbortPolicy:拒绝任务,且还抛出RejectedExecutionException异常,线程池默认策略
2) CallerRunPolicy:拒绝新任务进入,如果该线程池还没有被关闭,那么这个新的任务在执行线程中被调用
3) DiscardOldestPolicy: 如果执行程序尚未关闭,则位于头部的任务将会被移除,然后重试执行任务(再次失败,则重复该过程),这样将会导致新的任务将会被执行,而先前的任务将会被移除。
4)DiscardPolicy:没有添加进去的任务将会被抛弃,也不抛出异常。基本上为静默模式。

1.FixedThreadPool

由Executors的newFixedThreadPool方法创建。它是一种线程数量固定的线程池,当线程处于空闲状态时,他们并不会被回收,除非线程池被关闭。当所有的线程都处于活动状态时,新的任务都会处于等待状态,直到有线程空闲出来。FixedThreadPool只有核心线程,且该核心线程都不会被回收,这意味着它可以更快地响应外界的请求。jdk实现如下:

/*
     * @param nThreads the number of threads in the pool
     * @param threadFactory the factory to use when creating new threads
     * @return the newly created thread pool
     * @throws NullPointerException if threadFactory is null
     * @throws IllegalArgumentException if {@code nThreads <= 0}
     */
    public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>(),
                                      threadFactory);
    }

由此可以看出,FixedThreadPool没有额外线程,只存在核心线程,而且核心线程没有超时机制,而且任务队列没有长度的限制。

2.CachedThreadPool

由Executors的newCachedThreadPool方法创建,不存在核心线程,只存在数量不定的非核心线程,而且其数量最大值为Integer.MAX_VALUE。当线程池中的线程都处于活动时(全满),线程池会创建新的线程来处理新的任务,否则就会利用新的线程来处理新的任务,线程池中的空闲线程都有超时机制,默认超时时长为60s,超过60s的空闲线程就会被回收。和FixedThreadPool不同的是,CachedThreadPool的任务队列其实相当于一个空的集合,这将导致任何任务都会被执行,因为在这种场景下SynchronousQueue是不能插入任务的,SynchronousQueue是一个特殊的队列,在很多情况下可以理解为一个无法储存元素的队列。从CachedThreadPool的特性看,这类线程比较适合执行大量耗时较小的任务。当整个线程池都处于闲置状态时,线程池中的线程都会因为超时而被停止回收,几乎是不占任何系统资源。实现方式如下:

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
3.ScheduledThreadPool

通过Executors的newScheduledThreadPool方式创建,核心线程数量是固定的,而非核心线程是没有限制的,并且当非核心线程闲置时它会被立即回收,ScheduledThreadPool这类线程池主要用于执行定时任务和具有固定时期的重复任务,实现方法如下:

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }


 public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE,
              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
              new DelayedWorkQueue());
    }
4.SingleThreadExecutor

通过Executors的newSingleThreadExecutor方法来创建。这类线程池内部只有一个核心线程,它确保所有的任务都在同一个线程中按顺序执行。SingleThreadExecutor的意义在于统一所有外界任务一个线程中,这使得这些任务之间不需要处理线程同步的问题,实现方式如下:

public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

比较如下:

java 线程池 哪种效率最高 java线程池种类_jdk_02