ExecutorService每次给一个新的线程池有什么问题吗?

Is there any problem when ExecutorService gives every time a new thread pool?

我有以下代码,每次针对不同数量的线程执行:

class Worker<T> {
  public void process() {
      System.out.pritnln("Test");
  }
}

class Processor {
  private void doStuff(final Collection<Worker<V>> col) {
    final int size = col.size();
    if (size > 0) {
      final ExecutorService threads = Executors.newFixedThreadPool(col.size());
      for (Worker<V> w : col) {
        threads.submit(() -> w.process());
      }
      threads.shutdown();
    }
  }
}

每次在新的投票标识符中打印:

(pool-66-thread-1) Test

(pool-66-thread-2) Test

(pool-67-thread-1) Test

(pool-68-thread-1) Test

(pool-68-thread-3) Test

(pool-68-thread-2) Test

我想知道这是否是常见行为,或者在某些时候存在内存泄漏并且它会爆炸。它不应该重用之前的 pools 吗?

我怎么看,由于 threads.shutdown() 调用

,那些以前的池已经 shutdown

I wonder if this is the common behaviour, or at some point there is memory leak and will explode. Shouldn't it reuse previous pools?

好吧,您一直在显式创建新池。

// this creates a new pool
final ExecutorService threads = Executors.newFixedThreadPool(col.size());

至于内存泄漏,既然你正在关闭你的池,那应该没问题(但你应该这样做 finally 以防万一出现异常)。

如果你想 re-use 池(这很有意义),你应该使 threads 成为你的 Processor 的实例变量(并确保 Processor implements AutoCloseable 然后你在 close 方法中关闭了 threads

您正在函数中调用 Executors.newFixedThreadPool(),这会创建一个新的线程池。

这并不是 错误的 ,但它并不常见,并且与使用线程池背后的许多动机背道而驰。一种更标准的方法是在 Processor class 中创建一个线程池,并向其分配作业,如下所示:

class Processor {
    private final ExecutorService service = Executors.newFixedThreadExecutor(count);

    private void doStuff() {
        ...
        ...
        service.submit(() -> w.process());
    }
}

拥有线程池的想法是限制您正在创建的线程数量并重用已创建的线程,以避免在给定时间处理大量线程时不必要的拥塞并提高效率。现在您的代码的问题是它既不限制线程数也不重用。由于您只进行一些打印,因此您可能看不到拥塞,但如果您在 worker 中添加更多处理并继续并行调用它,那么您将看到完成处理的严重延迟。