在 Java 中,ExecutorService 本身是可以复用的,而且通常就应该复用,而不是频繁创建和销毁。下面从正确用法、复用方式、注意事项、常见错误几个方面说明。
ExecutorService 的设计目的就是复用线程池中的线程,而不是每次任务都创建新线程。
public class ExecutorManager {
// 全局复用
public static final ExecutorService EXECUTOR =
Executors.newFixedThreadPool(10);
}
提交任务:
ExecutorManager.EXECUTOR.submit(() -> {
System.out.println("Task running");
});
✅ 这是最推荐的方式
public class TaskService {
private final ExecutorService executor =
Executors.newFixedThreadPool(4);
public void doWork() {
executor.submit(() -> {
// 执行业务逻辑
});
}
}
✅ 适合:
@Configuration
public class ThreadPoolConfig {
@Bean
public ExecutorService executorService() {
return Executors.newFixedThreadPool(8);
}
}
@Service
public class OrderService {
@Autowired
private ExecutorService executorService;
public void process() {
executorService.submit(() -> {
// 异步处理
});
}
}
✅ Spring 容器管理生命周期,避免重复创建
public class ThreadPoolUtil {
public static final ExecutorService COMMON_POOL =
Executors.newFixedThreadPool(5);
}
✅ 适合工具类、临时任务
❌ 不适合复杂业务(不利于监控和管理)
public void runTask() {
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.submit(() -> {});
}
问题:
executor.shutdown(); // 一旦调用,线程池就不能再提交任务
✅ 复用线程池时:
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
executor.shutdown();
try {
if (!executor.awaitTermination(30, TimeUnit.SECONDS)) {
executor.shutdownNow();
}
} catch (InterruptedException e) {
executor.shutdownNow();
}
}));
不要所有任务共用一个线程池:
ExecutorService ioExecutor = Executors.newCachedThreadPool();
ExecutorService cpuExecutor = Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors()
);
✅ 一个线程池长期存在,反复提交任务
❌ 不要每次任务都 new 一个线程池
线程池要“长命”,任务要“短命”
如果你愿意,我也可以帮你:
ThreadPoolExecutor vs Executors只要把你的使用场景贴出来即可。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。