本篇文章主要是讲解如何使用Executors工具类创建线程池,看本篇之前建议同学们先去看看我发布的上一篇文章,即用new ThreadPoolExecutor()来创建线程池,里面讲解了线程池的参数使用方法和场景,熟悉了之后再来学习这一篇会更容易理解一些!因为Executors只是一个工具类,底层用的还是new ThreadPoolExecutor()来创建线程池的,而且用Executors创建线程池在高并发的情况下可能会有风险!
new ThreadPoolExecutor()方式创建线程池的链接在这里:
目录
3.1 newFixedThreadPool(int nThreads)
3.4newScheduledThreadPool(int corePoolSize)
1、四种方法:
分别是:
newFixedThreadPool(int nThreads)//创建固定线程数量的线程池
newSingleThreadExecutor() //创建单个线程池
newCachedThreadPool()//线程数量随着任务增加而增加,执行完毕任务空闲60s则会被回收
newScheduledThreadPool(int corePoolSize)//可以做定期执行任务,周期调度线程池,相当于加了定时器
2、代码演示:
非常简单
//测试Executors创建线程池
public class ThreadPool {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10); //创建固定线程数量的线程池
ExecutorService executorService1 = Executors.newSingleThreadExecutor(); //创建单个线程池
ExecutorService executorService2 = Executors.newCachedThreadPool(); //线程数量随着任务增加而增加,执行完毕任务空闲60s则会被回收
ExecutorService executorService3 = Executors.newScheduledThreadPool(10); //可以做定期执行任务,相当于加了定时器
executorService.execute(new MYThread());
executorService1.execute(new MYThread());
executorService2.execute(new MYThread());
executorService3.execute(new MYThread());
}
}
class MYThread implements Runnable{
@Override
public void run() {
System.out.println("打印线程池!");
}
}
3、源码分析:
3.1 newFixedThreadPool(int nThreads)
源码我们可以看到,最终还是使用ThreadPoolExecutor()来给我们创建线程,核心线程数就是我们传进入的参数
3.2 newSingleThreadExecutor()
这个方法给我们创建了一个核心线程数为0的线程
注意:当核心线程数为 0 时,当来了一个任务之后,会先将任务添加到任务队列同时判断当前工作的线程数是否为 0,如果为 0,则会创建线程来执行线程池的任务
这种创建方式能保证线程永远不死亡,当一个线程挂掉了(即当前工作的线程数为0),线程池会再给我们创建一个新的线程,以保证任务继续执行
如果是自己创建一个线程的话挂了就没了
3.3 newCachedThreadPool()
源码我们可以 看到,也是创建了一个核心线程数为0的线程,但是它把最大线程数量设置为int的最大值2147483647,临时线程的存活时间为60秒,这就完美解释了为什么newCachedThreadPool()这个线程池的线程数量会随着任务增加而增加,执行完毕任务空闲60s则会被回收。
3.4newScheduledThreadPool(int corePoolSize)
底层核心也是通过ThreadPoolExecutor创建线程池对象的
4、核心线程数的数量量应该怎么去配置呢?
一般情况下
计算密集型任务(做一些计算,例如计算1000之内和):核心线程数量=cpu的核数 + 1
IO密集型任务(读取文件数据或者通信):核心线程数量 = cpu的核数*2
电脑核数查看方式如下:
5、Executors工具类创建线程池的风险
我们实际开发中不建议使用Executors工具类来创建线程池,建议使用ThreadPoolExecutor()自己手动创建,能把控好核心线程数以及队列长度等。
在一些高并发的项目下很容易导致资源耗尽,也容易被黑客攻击出现资源耗尽的情况。
这就是我对Executors工具类的理解,希望能帮到大家,有问题的地方欢迎大家一起讨论!
后续会持续更新,欢迎大家一起讨论学习。
标签:Executors,创建,任务,源码,线程,new,ThreadPoolExecutor From: https://blog.csdn.net/rainingCSDN/article/details/143679700