JAVA 线程池的创建和使用(Executors) 作者:马育民 • 2020-01-28 22:54 • 阅读:10045 # 概述 要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚的情况下,很有可能配置的线程池不是较优的, java提供了```java.util.concurrent.Executors``` **工厂类**, 该类提供了一些静态方法,生成一些常用的线程池。 ### 不推荐使用 阿里巴巴开发手册,不建议使用 `Executors` 来创建线程池对象,会引发一些内存溢出,如下: [](/upload/0/0/1IX4d5ln6HtF.png) ### 推荐使用 推荐使用 [ThreadPoolExecutor线程池](https://www.malaoshi.top/show_1EF4skAs2E7o.html "ThreadPoolExecutor线程池") # Executors 创建线程池 通过 `Executors` 可以创建以下线程池 ### 可缓存线程池 - 创建的都是非核心线程 - 最大线程数为Interge的最大值,可能会导致内存溢出 - 空闲线程存活时间是1分钟 - 适用于生命周期短,密集而又频繁的任务,如果有大量耗时的任务,则不适该创建方式 **缺点:**该线程池允许创建的最大线程数量为Integer.MAX_VALUE,可能会创建出大量线程,导致OOM(内存溢出) ``` ExecutorService cachePool = Executors.newCachedThreadPool(); ``` ### 单线程池 - 创建一个核心线程 - 保证任务按FIFO顺序一个个执行 **缺点:** 该线程池使用的阻塞队列是 `LinkedBlockingQueue` 链表阻塞队列,默认容量为 `Integer.MAX_VALUE`,容量过大,可能会堆积大量的任务,从而造成OOM(内存溢出) ``` ExecutorService singlePool = Executors.newSingleThreadExecutor(); ``` ### 固定线程数线程池 - 创建固定数量的可复用的线程数 - 当线程数达到最大核心线程数,则加入队列等待有空闲线程时再执行 **缺点:** 该线程池使用的阻塞队列是 `LinkedBlockingQueue` 链表阻塞队列,默认容量为 `Integer.MAX_VALUE`,容量过大,可能会堆积大量的任务,从而造成OOM(内存溢出) ``` ExecutorService fixedPool = Executors.newFixedThreadPool(3); ``` ### 固定线程数,支持定时和周期性任务 - 可用于替代handler.postDelay和Timer定时器等延时和周期性任务 **缺点:**该线程池允许创建的最大线程数量为`Integer.MAX_VALUE`,可能会创建出大量线程,导致OOM(内存溢出) ``` ExecutorService scheduledPool = Executors.newScheduledThreadPool(5); ``` # 使用线程池步骤 1. 创建线程池对象。 2. 创建Runnable、CallThread 接口实现类对象。 3. 提交Runnable、CallThread 接口实现类对象。 4. 关闭线程池(一般不用线程池时,或者程序退出时)。 # 例子 ``` import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; public class TestExecutors { public static void main(String[] args) { CallThread ct1 = new CallThread("第A个"); FutureTask f1 = new FutureTask(ct1); CallThread ct2 = new CallThread("第B个"); FutureTask f2 = new FutureTask(ct2); CallThread ct3 = new CallThread("第C个"); FutureTask f3 = new FutureTask(ct3); ExecutorService es = Executors.newFixedThreadPool(3); es.submit(f1); es.submit(f2); es.submit(f3); es.shutdown(); try { System.out.println(f1.get()); System.out.println(f2.get()); System.out.println(f3.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } } class CallThread implements Callable{ private String name; public CallThread(String name){ this.name = name; } public Integer call() throws Exception { int sum = 0; for(int i = 0; i < 100; i++){ System.out.println(name + "---------------" + i); sum += i; } return sum; } } ``` 参考: https://blog.csdn.net/weixin_35414437/article/details/114229355 原文出处:http://malaoshi.top/show_1EF4skEfSxxr.html