要知道文章题目的答案,得先直到ThreadPoolExecutor这个类的构造方法参数
- corePoolSize:核心线程数,即线程池内维护的最小线程数
- maximumPoolSize:最大线程数
- keepAliveTime:线程空闲后被销毁前保留的时间
- unit:上面时间参数的单位
- workQueue:保存已提交但是未被执行的任务的队列
- threadFactory:创建线程池内线程的工厂类
- handler:拒绝策略
Executors的newFixedThreadPool、newSingleThreadExecutor、newCachedThreadPool等构造方法就是通过调整入参来生成不同线程池的。
当有新任务提交时,如果线程数小于核心线程数,线程池会立刻生成线程去执行任务。如果提交任务时线程数已经等于了核心线程数,那线程池会先尝试将任务放置在队列内缓存起来,后续空闲线程会逐个消费队列内部的任务。当队列是有界队列时,就有可能放不进队列,这时线程池会尝试创建新的线程,线程数不大于最大线程数即可。如果线程数也已经到达最大线程数,则会调用拒绝策略来拒绝执行任务。
阿里不允许使用Executors生成线程池,就是因为这些参数如果不仔细了解其作用与影响,是可能会出问题的,所以才提出这么个规则,逼得需要使用线程池的技术人员必须了解每个入参的含义,保证线上服务的稳定。
会出什么问题呢?最可能的问题是发生内存溢出。因为通过上面的分析我们直到,任务是会一直往队列里面放的,放不下了才可能开始拒绝,但是newFixedThreadPool、newSingleThreadExecutor这些线程池传入的队列都是LinkedBlockingQueue,也就是无界队列,缓存的任务数可能会无限增长。newCachedThreadPool这个线程池倒是没有使用无界队列而是使用一个即进即出的队列,但是这个线程池的最大线程数是Integer.MAX_VALUE,线程数会无限增长,同样会内存溢出。
原创文章,作者:geekgao,如若转载,请注明出处:https://www.geekgao.cn/archives/2412