Java代码规范之线程池不允许使用Executors创建
目录
该条规范是什么
该规范指出在Java编程中,不允许使用Executors
去创建线程池,而是通过ThreadPoolExecutor
的方式。这样的处理方式可以明确线程池的运行规则,规避资源耗尽的风险。
为什么这么规定
- 明确运行规则:使用
ThreadPoolExecutor
可以明确线程池的运行规则,包括核心线程数、最大线程数、任务队列等参数的设置,从而更好地控制线程池的行为。 - 避免资源耗尽:使用
Executors
返回的线程池对象存在一些弊端,如FixedThreadPool
和SingleThreadPool
允许的请求队列长度为Integer.MAX_VALUE
,可能导致请求堆积,造成内存耗尽;CachedThreadPool
和ScheduledThreadPool
允许的创建线程数量为Integer.MAX_VALUE
,可能会创建大量线程,导致内存耗尽。
多种主要用法及其代码示例
1. 使用ThreadPoolExecutor创建线程池
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Example {
public static void main(String[] args) {
int corePoolSize = 5; // 核心线程数
int maximumPoolSize = 10; // 最大线程数
long keepAliveTime = 60L; // 空闲线程存活时间(单位:秒)
ThreadPoolExecutor executor = new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
keepAliveTime,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>());
// 提交任务给线程池执行
executor.execute(new Task());
// 关闭线程池
executor.shutdown();
}
}
class Task implements Runnable {
@Override
public void run() {
// 任务执行的逻辑
}
}
2.使用Executors创建线程池(不推荐)
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Example {
public static void main(String[] args) {
int nThreads = 5; // 线程数
// 不推荐使用Executors创建线程池
ExecutorService executor = Executors.newFixedThreadPool(nThreads);
// 提交任务给线程池执行
executor.execute(new Task());
// 关闭线程池
executor.shutdown();
}
}
class Task implements Runnable {
@Override
public void run() {
// 任务执行的逻辑
}
}
hreadPoolExecutor和Executors在创建线程池方面的区别
ThreadPoolExecutor
和Executors
在创建线程池方面的区别:
ThreadPoolExecutor | Executors | |
---|---|---|
创建方式 | 通过构造函数创建,可自定义线程池的参数和配置 | 通过静态方法创建,提供了一些常见类型线程池的快速创建方式 |
灵活性 | 提供了更高的灵活性和自定义能力 | 提供了一些预定义的线程池实现,隐藏了底层细节 |
配置选项 | 可以自定义设置核心线程数、最大线程数、工作队列类型、饱和策略等 | 对于预定义的线程池,配置选项较少,不支持高度自定义 |
使用场景 | 适用于需要根据具体需求进行定制化配置和调整的场景 | 适用于简单的应用场景,不需要复杂配置和调整的场景 |
需要根据具体的需求和应用场景选择合适的方式。如果你需要更高的灵活性和自定义能力,以满足复杂的应用场景,那么使用ThreadPoolExecutor
会更合适。而如果你只需要一个简单且易于使用的线程池,并且不需要对线程池进行复杂的配置和调整,那么使用Executors
提供的预定义线程池实现会更方便。