被开发者抛弃的 Executors,错在哪儿?("开发者为何放弃Executors?问题出在哪里?")

原创
ithorizon 6个月前 (10-21) 阅读数 91 #后端开发

被开发者抛弃的 Executors,错在哪儿?

一、引言

在Java编程语言中,`Executors` 是一个用于创建和管理线程池的便捷工具类。然而,许多开发者在实际开发过程中往往会选择自己实现线程池管理,而不是直接使用 `Executors` 提供的线程池。那么,这究竟是为什么呢?本文将探讨 `Executors` 被开发者抛弃的原因,分析其存在的问题。

二、Executors 的基本用法

`Executors` 类提供了多种创建线程池的方法,以下是一些常用的方法:

ExecutorService executorService = Executors.newFixedThreadPool(10); // 创建一个固定大小的线程池

ExecutorService executorService2 = Executors.newCachedThreadPool(); // 创建一个可缓存的线程池

ExecutorService executorService3 = Executors.newSingleThreadExecutor(); // 创建一个单线程的线程池

三、Executors 存在的问题

尽管 `Executors` 提供了便捷的线程池创建方法,但它仍然存在一些问题,这些问题引起开发者选择放弃使用它。

1. 线程池参数固定

`Executors` 提供的线程池创建方法,如 `newFixedThreadPool`、`newCachedThreadPool` 和 `newSingleThreadExecutor` 等,其参数是固定的。这意味着开发者无法采取实际需求调整线程池的参数,如线程池大小、队列类型等。这在很多情况下会引起资源浪费或者性能问题。

2. 队列类型不灵活

`Executors` 默认使用的队列类型是 `LinkedBlockingQueue`,这在大多数情况下可以满足需求。然而,在某些场景下,开发者也许需要使用其他类型的队列,如 `SynchronousQueue`、`ArrayBlockingQueue` 等。`Executors` 并没有提供这种灵活性。

3. 线程池关闭问题

`ExecutorService` 提供了 `shutdown` 和 `shutdownNow` 方法用于关闭线程池。然而,在实际使用过程中,关闭线程池也许会遇到一些问题:

  • `shutdown` 方法只是将线程池的状态设置为关闭,但并不会立即停止正在执行的任务。这意味着在关闭线程池后,仍然也许有任务在执行,这也许会引起资源无法及时释放。
  • `shutdownNow` 方法会尝试停止所有正在执行的任务,但它返回的是一个尚未执行的任务列表,而不是已取消的任务列表。这也许会引起开发者在处理关闭线程池后的逻辑时产生混淆。

4. 性能问题

在某些场景下,使用 `Executors` 创建的线程池也许会出现性能问题。例如,在使用 `newFixedThreadPool` 创建固定大小的线程池时,如果任务提交速度大于线程处理速度,队列也许会迅速增长,引起内存溢出。

四、开发者怎样替代 Executors

为了避免 `Executors` 的问题,许多开发者选择使用 `ThreadPoolExecutor` 类直接创建线程池。以下是一个使用 `ThreadPoolExecutor` 创建线程池的示例:

ThreadPoolExecutor executor = new ThreadPoolExecutor(

10, // 核心线程数

20, // 最大线程数

60L, TimeUnit.SECONDS, // 非核心线程的空闲存活时间

new LinkedBlockingQueue<>(100), // 任务队列

Executors.defaultThreadFactory(), // 线程工厂

new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略

);

五、总结

`Executors` 作为Java中创建和管理线程池的便捷工具类,虽然在一定程度上简化了开发者的工作,但其存在的问题引起许多开发者选择放弃使用。开发者可以通过使用 `ThreadPoolExecutor` 类直接创建线程池,以获得更大的灵活性和更好的性能。在实际开发过程中,开发者应采取自己的需求合理选择线程池的创建方案。


本文由IT视界版权所有,禁止未经同意的情况下转发

文章标签: 后端开发


热门