Java ExecutorService-在方法中创建新实例,而不是每个类创建一个实例

Java ExecutorService-在方法中创建新实例,而不是每个类创建一个实例,java,multithreading,concurrency,threadpool,executorservice,Java,Multithreading,Concurrency,Threadpool,Executorservice,我应该在每个方法调用中创建新的ExecutorService还是在每个类中使用一个?就性能而言,哪个是首选选项 public class NotificationService { public void sendNotification(User recipient) { ExecutorService notificationsPool = Executors.newFixedThreadPool(10); // code no

我应该在每个方法调用中创建新的ExecutorService还是在每个类中使用一个?就性能而言,哪个是首选选项

public class NotificationService {

    public void sendNotification(User recipient) {

        ExecutorService notificationsPool = Executors.newFixedThreadPool(10);

        // code

        notificationsPool.shutdown();
    }
}


在您的第一个代码段中,
ExecutorService
是本地的,即在每个方法调用上创建一个新的
ExecutorService
,并且
ExecutorService
在方法末尾终止。因此,该方法下次运行时不会重用线程。在第二个代码段中,只要
NotificationService
实例处于活动状态,就会保留
ExecutorService
及其线程。正如您所看到的,不仅要GC的
ExecutorService
实例更少,而且要创建的线程更少,而且可以重用。作为额外的奖励,第二种方法在创建
ExecutorService
之后不会产生任何线程创建的预热时间

如果有多个
NotificationService
实例,则应将
notificationsPool
声明为
static
,以便在所有实例之间共享池及其线程


如果所需的线程数量因必须发送的通知数量而异,请使用缓存线程池(
ExecutorService#newCachedThreadPool()
),可能有一个上限。

这取决于两个问题:

  • 您需要什么级别的并行化
  • 您可以接受多少管理费用
你真的需要10个线程来解决函数中的问题吗?您是否需要能够处理该函数两次(从而为其提供20个线程)?你有足够的资源吗

或者,如果将线程池分配给类,会发生什么?这样做可能会遇到问题吗(由于线程池被使用而阻塞)

给定足够的资源,如果要解决的任务足够大,足以证明每次调用函数时创建该执行器的开销是合理的,那么选项1可能会更快。尽管老实说,我很难想象会有如此强烈的通知


因此,如果没有更多的信息,我会指向选项2(当然假设它是静态的)。此外,您还可以查看新的WorksteachingPool,它可能会帮助您使用精确的并行级别。

您不会根据性能选择此选项。您可以根据需要选择此选项。是否需要10个新线程才能向用户发送通知?如果您只使用10个可重用线程中的一个,只使用一次(假设向用户发送通知就是这样),那么拥有10个可重用线程池有什么意义呢?用户可能与多个密钥相关。然而,这不是一个好的代码示例,它在发布之前被修改过。
public class NotificationService {

    ExecutorService notificationsPool = Executors.newFixedThreadPool(10);

    public void sendNotification(User recipient) {

        // code
    }
}