关于java:阿里巴巴禁止使用-Executors-创建线程池为什么啊

47次阅读

共计 3526 个字符,预计需要花费 9 分钟才能阅读完成。

​起源:​blog.csdn.net/dabusiGin/article/details/105327873/

Executor 是不倡议的

Executors 类为咱们提供了各种类型的线程池,常常应用的工厂办法有:

public static ExecutorService newSingleThreadExecutor()
public static ExecutorService newFixedThreadPool(int nThreads)
public static ExecutorService newCachedThreadPool()
public static ScheduledExecutorService newSingleThreadScheduledExecutor()
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

书写一段很简略的测试代码:

public class ThreadDemo {public static void main(String[] args) {ExecutorService es = Executors.newSingleThreadExecutor();
 }
}

当咱们用阿里巴巴的 P3C 查看代码时,会被教育的!!!!

阿里爸爸是不容许这么创立线程池的,下面的正告写的很明确“线程池不容许应用 Executors 去创立,而是通过 ThreadPoolExecutor 的形式,这样的解决形式让写的同学更加明确线程池的运行规定,躲避资源耗尽的危险。”(PS:很难得在编译器中看到中文提醒,对于英语不好的同学来说,几乎是福音,喜极而泣!!!!)

强制应用 ThreadPoolExecutor

咱们应用 ThreadPoolExecutor 创立线程池:

public class ThreadDemo {public static void main(String[] args) {
  ExecutorService es = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,
    new LinkedBlockingQueue<Runnable>(10), Executors.defaultThreadFactory(),
    new ThreadPoolExecutor.DiscardPolicy());
 }
}

此时,再用 P3C 查看代码,终于没有报错了。

在富丽的分隔符之后,咱们还是有必要从 JDK 源码的层面深挖一下其中的原理。

首先是静态方法newSingleThreadExecutor()newFixedThreadPool(int nThreads)newCachedThreadPool()。咱们来看一下其源码实现(基于 JDK8)。

public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
}

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
}

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
}

通过查看源码咱们晓得上述三种静态方法的外部实现均应用了 ThreadPoolExecutor 类。难怪阿里爸爸会倡议通过 ThreadPoolExecutor 的形式实现,原来 Executors 类的静态方法也是用的它,只不过帮咱们配了一些参数而已。

第二是 ThreadPoolExecutor 类的构造方法。既然当初要间接应用 ThreadPoolExecutor 类了,那么其中的初始化参数就要咱们本人配了,理解其构造方法势在必行。

ThreadPoolExecutor类一共有四个构造方法,咱们只须要理解之中的一个就能够了,因为其余三种构造方法只是帮咱们配置了一些默认参数,最初还是调用了它。

public ThreadPoolExecutor(int corePoolSize,
            int maximumPoolSize,
            long keepAliveTime,
            TimeUnit unit,
            BlockingQueue<Runnable> workQueue,
            ThreadFactory threadFactory,
            RejectedExecutionHandler handler)

其中的参数含意是:

  • corePoolSize:线程池中的线程数量;
  • maximumPoolSize:线程池中的最大线程数量;
  • keepAliveTime:当线程池线程数量超过 corePoolSize 时,多余的闲暇线程会在多长时间内被销毁;
  • unit:keepAliveTime 的工夫单位;
  • workQueue:工作队列,被提交然而尚未被执行的工作;
  • threadFactory:线程工厂,用于创立线程,个别状况下应用默认的,即 Executors 类的静态方法 defaultThreadFactory();handler:回绝策略。当工作太多来不及解决时,如何回绝工作。

对于这些参数要有以下理解:

corePoolSize 与 maximumPoolSize 的关系

首先 corePoolSize 必定是 <= maximumPoolSize。

其余关系如下:

  • 若以后线程池中线程数 < corePoolSize,则每来一个工作就创立一个线程去执行;
  • 若以后线程池中线程数 >= corePoolSize,会尝试将工作增加到工作队列。如果增加胜利,则工作会期待闲暇线程将其取出并执行;
  • 若队列已满,且以后线程池中线程数 < maximumPoolSize,创立新的线程;
  • 若以后线程池中线程数 >= maximumPoolSize,则会采纳回绝策略(JDK 提供了四种,上面会介绍到)。

留神:关系 3 是针对的有界队列,无界队列永远都不会满,所以只有前 2 种关系。

workQueue

参数 workQueue 是指提交但未执行的工作队列。若以后线程池中线程数 >=corePoolSize 时,就会尝试将工作增加到工作队列中。次要有以下几种:

  • SynchronousQueue:间接提交队列。SynchronousQueue 没有容量,所以实际上提交的工作不会被增加到工作队列,总是将新工作提交给线程执行,如果没有闲暇的线程,则尝试创立新的线程,如果线程数量曾经达到最大值(maximumPoolSize),则执行回绝策略。
  • LinkedBlockingQueue:无界的工作队列。当有新的工作来到时,若零碎的线程数小于 corePoolSize,线程池会创立新的线程执行工作;当零碎的线程数量等于 corePoolSize 后,因为是无界的工作队列,总是能胜利将工作增加到工作队列中,所以线程数量不再减少。若工作创立的速度远大于工作解决的速度,无界队列会快速增长,直到内存耗尽。

handler

JDK 内置了四种回绝策略:

  • DiscardOldestPolicy 策略:抛弃工作队列中最早增加的工作,并尝试提交当前任务;
  • CallerRunsPolicy 策略:调用主线程执行被回绝的工作,这提供了一种简略的反馈管制机制,将升高新工作的提交速度。
  • DiscardPolicy 策略:默默抛弃无奈解决的工作,不予任何解决。
  • AbortPolicy 策略:间接抛出异样,阻止零碎失常工作。

至此,咱们间接 new ThreadPoolExecutor 类就不必慌了!!!!

近期热文举荐:

1.1,000+ 道 Java 面试题及答案整顿(2022 最新版)

2. 劲爆!Java 协程要来了。。。

3.Spring Boot 2.x 教程,太全了!

4. 别再写满屏的爆爆爆炸类了,试试装璜器模式,这才是优雅的形式!!

5.《Java 开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞 + 转发哦!

正文完
 0