ExecutorService - 在方法中创建新实例vs每个类创建一个实例
我应该在每个方法调用中创建新的ExecutorService还是每个类使用一个?在性能方面哪个是首选?ExecutorService - 在方法中创建新实例vs每个类创建一个实例
public class NotificationService {
public void sendNotification(User recipient) {
ExecutorService notificationsPool = Executors.newFixedThreadPool(10);
// code
notificationsPool.shutdown();
}
}
或者
public class NotificationService {
ExecutorService notificationsPool = Executors.newFixedThreadPool(10);
public void sendNotification(User recipient) {
// code
}
}
在您的第一个代码段的ExecutorService
是本地的,即,一个新的ExecutorService
在每个方法调用创建和ExecutorService
在方法结束时被终止。因此,下次运行该方法时线程不会重用。在第二个片段中,只要NotificationService
实例处于活动状态,ExecutorService
及其线程就会保留。正如你所看到的,不仅有更少的ExecutorService
实例需要GC'd,而且还有更少的线程可以创建,并且可以重复使用。作为额外的奖励,第二种方法在创建ExecutorService
之后不会产生线程创建的任何预热时间。
如果您有多个NotificationService
实例,则应声明notificationsPool
为static
,以便在所有实例之间共享池及其线程。
如果所需的线程数量取决于必须发送的通知的数量,请使用缓存的线程池(ExecutorService#newCachedThreadPool()
),可能有一个上限。
这取决于两个问题:
- 你需要什么级别的并行化?
- 你可以接受多少开销?
你真的需要10个线程来解决函数中的问题吗?你需要能够,两次处理该函数(从而给它20个线程)?你是否有资源,这样做?
或者如果将一个threadPool分配给该类会发生什么?您是否可能遇到问题(由于线程池被用尽而阻塞)?
如果给定足够的资源,如果要解决的任务足够大,以证明每次调用该函数时创建该执行程序的开销,则选项1可能会更快。虽然老实说,我几乎无法想象这个激烈的通知。
因此,没有更多的信息,我会指向选项2(假设它当然是静态的)。你也可以看看新的WorkStealingPool,它可以帮助你使用精确的并行度。
您不会根据性能选择此选项。你根据需要选择它。你是否需要10个新线程向用户发送通知?如果只使用其中一个线程,那么拥有10个可重用线程池有什么意义?(假设这就是向用户发送通知的方法)? –
用户可能与1个以上的密钥相关。但是,这不是在发布之前修改的好代码示例。 – Justas