并发编程系列之线程池工厂类——Executors

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 并发编程系列之线程池工厂类——Executors

并发编程系列之线程池工厂类:Executors

前言

上节讲了讲自定义线程池,今天我们来聊聊线程池框架,在实际开发中我们还是基本使用线程框架Executor给我们提供的一些工具类,Java提供的Executor都在JUC(java.util.concurrent)包下面,主要包括:线程池工厂类Executors,线程池实现类ThreadPoolExecutor等,今天呢我们主要聊聊Executors,看看通过Executors我们可以做什么?OK,不多说废话,我们马上进入今天的主题,让我们扬帆起航,开启今天的并发之旅吧。

并发编程系列之线程池工厂类:Executors

什么是Executors?

Executors,扮演的是线程工厂的角色,一定要与Executor相区分开,Executors只是Executor框架中的一个工厂类而已,通过Executors我们可以创建特定功能的线程池(ThreadPoolExecutor),通过这句话你是不是对Executors和ThreadPoolExecutor的关系有了一定的认识,这两个都是Executor框架中的一部分(关于Executor框架的各个成员组成这里就先不做说明,今天主要是学会怎么使用线程工厂创建线程池)。

并发编程系列之线程池工厂类:Executors

如何使用Executors?

线程池ThreadPoolExecutor通常都是通过Executors来创建的,我们可以根据自己的需求创建下面几种不同作用的线程池:


// 创建一个固定数量的线程池
ExecutorService ExecutorService1 = Executors.newFixedThreadPool(10);
// 返回一个可根据实际情况调整线程个数的线程池
ExecutorService ExecutorService2 = Executors.newCachedThreadPool();
// 创建一个线程数量为1的线程池
ExecutorService ExecutorService3 = Executors.newSingleThreadExecutor();
// 返回一个ScheduledExecutorService对象,该对象也是调用父类的线程池方法,类似newFixedThreadPool
ScheduledExecutorService ScheduledExecutorService = Executors.newScheduledThreadPool(5);

线程池的使用之前讲自定义线程池已经说过了,主要也就是:

  • execute向线程池提交任务
  • shutdown和shutdownNow关闭线程池
  • shutdown和shutdownNow关闭线程池

    本文由“壹伴编辑器”提供技术支持

    newFixedThreadPool:该方法返回一个固定数量的线程池,该方法的线程数量始终不变,当有任务提交时,若线程池中有空闲线程,则立即执行,若没有,则会被缓存在一个任务队列中等待有空闲的线程再去执行;(核心线程数等于最大线程数,默认空闲时间为0,空闲立马销毁),该方法有2个实现,我们看下面源码:

    
    public static ExecutorService newFixedThreadPool(int nThreads) {
            return new ThreadPoolExecutor(nThreads, nThreads,
                                          0L, TimeUnit.MILLISECONDS,
                                          new LinkedBlockingQueueRunnable());
        }
    
     public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
            return new ThreadPoolExecutor(nThreads, nThreads,
                                          0L, TimeUnit.MILLISECONDS,
                                          new LinkedBlockingQueueRunnable(),
                                          threadFactory);
        }
    

    再分别看下这2个方法在线程池中的实现:

    
    // 我们会发现没有传入线程工厂的方法调用了一个默认的线程工厂
    public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueueRunnable workQueue) {
            this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
                 Executors.defaultThreadFactory(), defaultHandler);
        }
    
    // 而有传入线程工厂的方法调用自己传入的线程工厂
     public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueueRunnable workQueue,
                                  ThreadFactory threadFactory) {
            this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
                 threadFactory, defaultHandler);
        }
    

    本文由“壹伴编辑器”提供技术支持

    newSingleThreadExecutor:创建一个线程数量为1的线程池,若空闲则执行,否则入队列等待被执行;(核心线程数量为1,最大线程数量也为1,空闲等待时间为0),该方法也有2个实现,一个带自定义的线程工厂,一个不带:

    
    public static ExecutorService newSingleThreadExecutor() {
            return new FinalizableDelegatedExecutorService
                (new ThreadPoolExecutor(1, 1,
                                        0L, TimeUnit.MILLISECONDS,
                                        new LinkedBlockingQueueRunnable()));
        }
    
     public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
            return new FinalizableDelegatedExecutorService
                (new ThreadPoolExecutor(1, 1,
                                        0L, TimeUnit.MILLISECONDS,
                                        new LinkedBlockingQueueRunnable(),
                                        threadFactory));
        }
    

    本文由“壹伴编辑器”提供技术支持

    newCachedThreadPool:返回一个可根据实际情况调整线程个数的线程池,不限制最大线程数量,若有任务则没线程时则创建线程,每个线程空闲等待时间为60秒,60秒后如果该线程没有任务可执行,则被回收;(核心线程数量为0,最大线程数量为最大,空闲等待时间为60s)

    
    public static ExecutorService newCachedThreadPool() {
            return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                          60L, TimeUnit.SECONDS,
                                          new SynchronousQueueRunnable());
        }
    
       public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
            return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                          60L, TimeUnit.SECONDS,
                                          new SynchronousQueueRunnable(),
                                          threadFactory);
        }
    

    本文由“壹伴编辑器”提供技术支持

    newScheduledThreadPool:返回一个ScheduledExecutorService对象,该线程池可以指定线程数量

    
    // 返回一个ScheduledExecutorService对象
    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
            return new ScheduledThreadPoolExecutor(corePoolSize);
        }
    
    // 调了父类super的方法里面还是一个ThreadPoolExecutor
    public ScheduledThreadPoolExecutor(int corePoolSize) {
            super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
                  new DelayedWorkQueue());
        }
    // 父类super中的ThreadPoolExecutor
     public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueueRunnable workQueue) {
            this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
                 Executors.defaultThreadFactory(), defaultHandler);
        }
    

    相关文章:

    并发编程系列之线程池工厂类:Executors

    原文始发于微信公众号(Justin的后端书架):

    本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

    本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

    原文链接:blog.ouyangsihai.cn >> 并发编程系列之线程池工厂类——Executors


     上一篇
    并发编程系列之并发编程的认识 并发编程系列之并发编程的认识
    前言 今天我们开始接触并发编程的讲解,首先我们要知道并发编程的目的是什么?一个目的,为了让程序员运行的更快,但是有一点我们要知道,并不是启动越多的线程就能让程序更大限度的并发执行,在并发编程的开发中,如果希望使用更多的线程来加快程序的运行,
    2021-04-05
    下一篇 
    并发编程系列之Semaphore 并发编程系列之Semaphore
    前言 上节我们介绍了Java中的并发工具类CountDownLatch和Cyclicbarrier,今天我们再来说说另外两个并发工具类:Semaphore(信号量)和Exchanger(交换者),首先我们先来说说信号量这个东西,结合我
    2021-04-05