ThreadPoolExecutor简析

2018-08-22  本文已影响9人  Sherlockkk

为什么使用线程池

使用线程池的好处是减少在创建和销毁线程上所花的时间和系统资源的开销,节省资源,提高效率。如果不使用线程池,有可能会造成系统创建大量同类线程而导致内存耗尽或者“过度切换”的问题。所以线程资源最好由线程池提供,不要在应用中自行显示创建线程。

Executor

Executor是java中线程池的核心接口,只有一个方法execute(Runnable command)

public interface Executor {

    /**
     * Executes the given command at some time in the future.  The command
     * may execute in a new thread, in a pooled thread, or in the calling
     * thread, at the discretion of the {@code Executor} implementation.
     *
     * @param command the runnable task
     * @throws RejectedExecutionException if this task cannot be
     * accepted for execution
     * @throws NullPointerException if command is null
     */
    void execute(Runnable command);
}

类关系说明

ThreadPoolExecutor是Executor接口的主要实现类

类关系类关系

ExecutorService是Executor的子接口,增加了一些对线程池的控制方法,关闭线程池,批量调用等
AbstractExecutorService是一个抽象类,对ExecutorService的方法提供了默认实现,ThreadPoolExecutor继承此类

ThreadPoolExecutor

构造方法

ThreadPoolExecutor是线程池的真正实现类,可以通过构造方法的各种参数组合来配置不同的线程池。构造方法有以下四种

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         Executors.defaultThreadFactory(), defaultHandler);
}
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         threadFactory, defaultHandler);
}
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          RejectedExecutionHandler handler) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         Executors.defaultThreadFactory(), handler);
}
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) {
    if (corePoolSize < 0 ||
        maximumPoolSize <= 0 ||
        maximumPoolSize < corePoolSize ||
        keepAliveTime < 0)
        throw new IllegalArgumentException();
    if (workQueue == null || threadFactory == null || handler == null)
        throw new NullPointerException();
    this.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
}

先来解释一下各个参数:

主要方法

当然还有一系列的getXxx方法,方便对线程池的监控

getXxx方法getXxx方法

总结

引用《阿里巴巴Java开发手册》中的一段话来总结一下

【强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

说明:Executors 返回的线程池对象的弊端如下:

1)FixedThreadPool 和 SingleThreadPool:

允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。

2)CachedThreadPool 和 ScheduledThreadPool:

允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。

一个线程池在应用中如果不再被引用且没有剩余的线程时,这个线程池会被自动的shutdown。因此如果你想在忘记执行shutdown方法时也能正常的关闭线程池,建议设置一个有限的keepAliveTime,同时也执行下 allowCoreThreadTimeOut(true)

enjoy conding...

上一篇下一篇

猜你喜欢

热点阅读