线程池ThreadPoolExecutor构造方法详解

为什么用线程池?

频繁的创建和销毁线程需要时间,会大大降低系统的效率。线程池就是一个容纳多个线程的 容器,池中的线程可以反复使用,节省了大量的时间和资源。

使用线程池主要为了解决以下几个问题:

  • 通过重用线程池中的线程,来减少每个线程创建和销毁的性能开销。
  • 对线程进行一些维护和管理,比如定时开始,周期执行,并发数控制等等。

创建和使用线程池:

创建线程池有以下两种方法:

  • 通过 Executors 类的静态方法
  • 通过 ThreadPoolExecutor 的构造方法,自定义线程池

通过看 Executors 的源码可知,Executors 类创建线程池的时候实质就是调用 ThreadPoolExecutor 类的构造方法来创建。除此之外,阿里巴巴Java开发手册中不允许使用 Executors 来创建线程池,而是通过 ThreadPoolExecutor 的方式。

使用 ThreadPoolExecutor 构造方法来创建线程池及参数详解:

ThreadPoolExecutor  源码:

 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.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

参数 1 :corePoolSize  核心线程数量,即使闲置,也仍然会存活。默认情况下核心线程会一直存活,除非将 allowCoreThreadTimeOut设置为 true

参数 2:maximumPoolSize  最大线程数量,线程池里能容下的最大线程数,包括核心线程和非核心线程。

参数 3:keepAliveTime  线程存活时间。当线程池中的线程数大于核心线程数时,keepAliveTime  表示空闲的非核心线程数 能存活的最大时长。

参数 4:unit  参数3的时间单位

参数 5:BlockingQueue 阻塞队列,核心线程已满,但最大线程未满的情况下,新创建的线程会被放入阻塞队列中,常用的有三种队列,SynchronousQueue, LinkedBlockingDeque,ArrayBlockingQueue

参数 6:ThreadFactory 线程工厂,ThreadFactory是一个接口,只有一个方法,提供创建新线程的功能。

public interface ThreadFactory {
  Thread newThread(Runnable r);
}

参数7:RejectedExecutionHandler 拒绝策略,当最大线程数已满时,新创建的线程会被拒绝策略拒绝。具体有一下几种策略:

不直接丢弃任务的两种策略:

AbortPolicy:抛出RuntimeException,会中断该线程的调用过程。

CallerRunsPolicy:线程不进入线程池,在线程池外由调用者线程去执行。

直接丢弃任务的两种策略:

DiscardPolicy:丢弃当前要加入队列的新线程。

DiscardOldestPolicy:丢弃队列中最旧的线程。

使用线程池:不必通过 Thread或Runnable 显式地创建线程,直接给线程分配任务即可

// 创建线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(4,4,10, TimeUnit.SECONDS,new LinkedBlockingDeque<Runnable>());
// 给线程池中的线程添加任务
executor.execute(new Runnable() {
     @Override
     public void run() {

     }
});
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页