Executors线程池讲解

35 阅读5分钟

五种线程池

Java通过Executors提供五种线程池,分别为:

1、newSingleThreadExecutor

创建使用在无界队列上操作的单个工作线程的执行器。(但是请注意,如果这个单线程在关闭之前的执行过程中由于失败而终止,如果需要执行后续任务,将会有一个新的线程取代它。)任务保证按顺序执行,并且在任何给定时间活动的任务不超过一个。与newFixedThreadPool(1)不同,返回的执行器保证不会被重新配置以使用其他线程。 返回: 新创建的单线程执行器

2、newFixedThreadPool

创建一个线程池,该线程池重用在共享无界队列上操作的固定数量的线程,并在需要时使用提供的ThreadFactory创建新线程。在任何时候,最多有nThreads线程处于活动状态,正在处理任务。如果在所有线程都处于活动状态时提交额外的任务,它们将在队列中等待,直到一个线程可用。如果任何线程在关闭之前的执行过程中由于失败而终止,如果需要执行后续任务,则会有一个新线程取代它的位置。在显式关闭池之前,池中的线程将一直存在。 参数: nThreads——池中的线程数 创建新线程时使用的工厂 返回: 新创建的线程池 抛出: NullPointerException -如果threadFactory是空的 IllegalArgumentException -如果nThreads <= 0

3、newScheduledThreadPool

创建一个线程池,该线程池可以调度命令在给定延迟后运行或定期执行。 参数: corePoolSize—要保留在池中的线程数,即使它们是空闲的 threadFactory——执行器创建新线程时使用的工厂 返回: 新创建的调度线程池 抛出: IllegalArgumentException -如果corePoolSize < 0 NullPointerException -如果threadFactory是空的

4、newCachedThreadPool

创建一个线程池,该线程池根据需要创建新线程,但在以前构造的线程可用时重用它们。这些池通常会提高执行许多短期异步任务的程序的性能。执行调用将重用先前构造的线程(如果可用)。如果没有可用的现有线程,将创建一个新线程并将其添加到池中。60秒内未使用的线程将被终止并从缓存中删除。因此,长时间保持空闲状态的池不会消耗任何资源。请注意,可以使用ThreadPoolExecutor构造函数创建具有相似属性但不同细节(例如,超时参数)的池。 返回: 新创建的线程池

5、newWorkStealingPool

创建一个线程池,该线程池维护足够的线程以支持给定的并行级别,并且可以使用多个队列来减少争用。并行性级别对应于积极参与或可用参与任务处理的最大线程数。实际的线程数可以动态地增加和减少。工作窃取池不能保证所提交任务的执行顺序。 参数: 并行度——目标并行度级别 返回: 新创建的线程池 抛出: IllegalArgumentException -如果并行度<= 0 自: JDK1.8

ThreadPoolExecutor类讲解

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         threadFactory, defaultHandler);
}

1、参数讲解

maximumPoolSize:最大线程数
keepAlivedTime:线程存活时间
unit:线程存活时间单位
workQueue:阻塞队列,用来存放待处理的任务
threadFactory:线程工厂,用来创建线程池中的工作线程
handler:拒绝策略,当线程池处于满负荷状态时,无法处理后续进来的任务,便会采用拒绝策略。\

四种拒绝策略讲解

1、AbortPolicy:默认使用策略,丢弃该任务总是抛出RejectedExecutionException


/**
 * A handler for rejected tasks that throws a
 * {@link RejectedExecutionException}.
 *
 * This is the default handler for {@link ThreadPoolExecutor} and
 * {@link ScheduledThreadPoolExecutor}.
 */
public static class AbortPolicy implements RejectedExecutionHandler {
    /**
     * Creates an {@code AbortPolicy}.
     */
    public AbortPolicy() { }

    /**
     * Always throws RejectedExecutionException.
     *
     * @param r the runnable task requested to be executed
     * @param e the executor attempting to execute this task
     * @throws RejectedExecutionException always
     */
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        throw new RejectedExecutionException("Task " + r.toString() +
                                             " rejected from " +
                                             e.toString());
    }
}

2、CallerRunsPolicy:只要线程池没有被shutdown(),提交任务的线程通过执行r.run()方法直接以普通的方法执行


/**
 * A handler for rejected tasks that runs the rejected task
 * directly in the calling thread of the {@code execute} method,
 * unless the executor has been shut down, in which case the task
 * is discarded.
 */
public static class CallerRunsPolicy implements RejectedExecutionHandler {
    /**
     * Creates a {@code CallerRunsPolicy}.
     */
    public CallerRunsPolicy() { }

    /**
     * Executes task r in the caller's thread, unless the executor
     * has been shut down, in which case the task is discarded.
     *
     * @param r the runnable task requested to be executed
     * @param e the executor attempting to execute this task
     */
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        if (!e.isShutdown()) {
            r.run();
        }
    }
}

3、DisCardPlicy:直接丢弃,不做任务处理


/**
 * A handler for rejected tasks that silently discards the
 * rejected task.
 */
public static class DiscardPolicy implements RejectedExecutionHandler {
    /**
     * Creates a {@code DiscardPolicy}.
     */
    public DiscardPolicy() { }

    /**
     * Does nothing, which has the effect of discarding task r.
     *
     * @param r the runnable task requested to be executed
     * @param e the executor attempting to execute this task
     */
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    }
}

4,DisCardOldestPolicy::只要线程池没有被shutdown(),则通过e.getQueue().poll()把队列头部等待最久 的任务丢弃,然后把当前任务通过execute()方法提交到阻塞队列


/**
 * A handler for rejected tasks that discards the oldest unhandled
 * request and then retries {@code execute}, unless the executor
 * is shut down, in which case the task is discarded. This policy is
 * rarely useful in cases where other threads may be waiting for
 * tasks to terminate, or failures must be recorded. Instead consider
 * using a handler of the form:
 * <pre> {@code
 * new RejectedExecutionHandler() {
 *   public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
 *     Runnable dropped = e.getQueue().poll();
 *     if (dropped instanceof Future<?>) {
 *       ((Future<?>)dropped).cancel(false);
 *       // also consider logging the failure
 *     }
 *     e.execute(r);  // retry
 * }}}</pre>
 */
public static class DiscardOldestPolicy implements RejectedExecutionHandler {
    /**
     * Creates a {@code DiscardOldestPolicy} for the given executor.
     */
    public DiscardOldestPolicy() { }

    /**
     * Obtains and ignores the next task that the executor
     * would otherwise execute, if one is immediately available,
     * and then retries execution of task r, unless the executor
     * is shut down, in which case task r is instead discarded.
     *
     * @param r the runnable task requested to be executed
     * @param e the executor attempting to execute this task
     */
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        if (!e.isShutdown()) {
            e.getQueue().poll();
            e.execute(r);
        }
    }
}