​Executors源码学习

时间:2022-07-23
本文章向大家介绍​Executors源码学习,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

在学习并发线程池的时候,我们基本都已经学习了一下常见的线程。但是我们发现Executors这样一个类的存在。那么这个类是干什么的?其实在分析ThreadPoolExecutor和ScheledThreadPoolExecutor的时候我们就注意到有一个execute方法了。除此之外还有其他一些方法。当时没有找到是谁在调用。在分析计划任务线程池执行器的时候感觉应该是Executors这个类调用的。那么我们来学习一个Executors究竟是何方圣神吧。

从结构图上看出这个类有一些内部类,显然内部类都是定制的。除此之外此类提供了一些创建线程池的工具类。所以看的出来这块的功能还是类似工具类。

//创建一个固定线程池(最大和核心线程数相同)
   public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS, LinkedBlockingQueue<Runnable>());
    }


    //创建一个forkjoin线程池
    public static ExecutorService newWorkStealingPool(int parallelism) {
        return new ForkJoinPool(parallelism, ForkJoinPool.defaultForkJoinWorkerThreadFactory,null, true);
    }
    
    //创建一个forkjoin线程池
    public static ExecutorService newWorkStealingPool() {
        return new ForkJoinPool(Runtime.getRuntime().availableProcessors(),ForkJoinPool.defaultForkJoinWorkerThreadFactory,null, true);
    }


    //创建一个固定线程池(核心线程和最大线程相同)
    public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
        return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(),threadFactory);
    }


    //创建一个单线程的线程池
    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));
    }


//创建一个单线程的线程池
    public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
        return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(),threadFactory));
    }


    //创建一个自动增长的线程池
    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());
    }
//创建一个自动增长的线程池
    public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>(),threadFactory);
    }
//创建一个单线程的计划线程池
    public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
        return new DelegatedScheduledExecutorService(new ScheduledThreadPoolExecutor(1));
    }


//创建一个计划线程池
    public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
        return new DelegatedScheduledExecutorService(new ScheduledThreadPoolExecutor(1, threadFactory));
    }
//创建一个计划线程池
    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }
//创建要给计划线程池
    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory) {
        return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
    }
//创建一个DelegatedExecutorService
    public static ExecutorService unconfigurableExecutorService(ExecutorService executor) {
        if (executor == null)
            throw new NullPointerException();
        return new DelegatedExecutorService(executor);
    }
//创建一个DelegatedExecutorService
    public static ScheduledExecutorService unconfigurableScheduledExecutorService(ScheduledExecutorService executor) {
        if (executor == null)
            throw new NullPointerException();
        return new DelegatedScheduledExecutorService(executor);
    }

上述方法返回的实体其最终都实现了Executor接口,而Executor接口就只提供了方法execute方法。也就是最终都调用的子类的execute方法。

public interface Executor {
    void execute(Runnable command);
}

在现实开发中我们使用比较多的还是ThreadPoolExecutor。但是要注意的是阿里java开发规范中禁止使用Executors方法创建线程。因为除了单线程池和固定线程池外;

Executors创建的线程数量都是采用了Integer.MAX_VALUE;也就是没有做任何限制。

除此之外任务队列均没有限制容量,也就是如果有大量的请求过来就会阻塞到任务队列中。如果数据量比较大的话容易产生OOM问题。

所以我们在创建线程池的时候最好还是手动去创建吧。对于核心线程和最大线程数量都要仔细考虑。除此之外对于线程池的任务队列也要将给个容量。防止堆溢出问题。