使用Executors.newSingleThreadExecutor()的方便场景示例

7
请问有没有真实的例子可以说明在什么情况下使用工厂方法会更加方便?
newSingleThreadExecutor public static ExecutorService newSingleThreadExecutor() 创建一个使用单个工作线程和无界队列的 Executor。 (但请注意,如果此单个线程在关闭之前由于执行期间的故障而终止,则需要一个新线程来执行后续任务。) 保证按顺序执行任务,并且任何给定时间内最多只能有一个任务处于活动状态。 与否则相同的 newFixedThreadPool(1) 相比,返回的Executor保证不可重新配置以使用额外的线程。
谢谢。
4个回答

15
请问有没有人能举一个现实生活中使用[newSingleThreadExecutor()工厂方法]比其他方法方便的例子?
假设您是在询问何时使用单线程线程池而不是固定或缓存线程池。
当我有很多任务要运行,但只想让一个线程来完成时,我会使用单线程执行器。这与使用1个固定线程池相同。通常这是因为我们不需要并行运行它们,它们是后台任务,我们也不想占用太多系统资源(CPU、内存、IO)。我希望将各种任务处理为CallableRunnable对象,因此ExecutorService是最佳选择,但我只需要一个线程来运行它们。
例如,我有许多计时器任务,我会注入进Spring。我有两种类型的任务,我的“短期运行”任务在单线程池中运行。即使在我的系统中有几百个任务,也只有一个线程执行它们所有。它们执行例行任务,如检查磁盘空间、清理日志、转储统计信息等。对于时间关键的任务,我则在缓存线程池中运行。
另一个例子是我们有一系列的合作伙伴集成任务。它们不需要很长时间,而且运行频率相当低,我们不希望它们与其他系统线程竞争,因此它们在单线程执行器中运行。
第三个例子是我们有一个有限状态机,每个状态变异体都将作业从一个状态转移到另一个状态,并在单线程池中注册为Runnable。即使我们有数百个突变剂,每次只有一个任务是有效的,因此为任务分配超过一个线程是没有意义的。

1
因为我们不希望它们并行运行并消耗过多的CPU资源@Rollerball。我添加了另一个示例来说明这一点。 - Gray

3
除了已经提到的原因,当您需要保证顺序时,您会想要使用单线程执行器,即您需要确保提交的任何任务始终按提交顺序发生。

2
Executors.newSingleThreadExecutor()Executors.newFixedThreadPool(1) 之间的区别很小,但在设计库API时可能有帮助。如果您将返回的 ExecutorService 传递给您库的用户,并且该库仅在执行器使用单个线程(任务不是线程安全的)时才能正常工作,则最好使用 Executors.newSingleThreadExecutor()。否则,库的用户可能会通过以下方式破坏它:
ExecutorService e = myLibrary.getBackgroundTaskExecutor();
((ThreadPoolExecutor)e).setCorePoolSize(10);

对于Executors.newSingleThreadExecutor(),它不可能实现。


0

当您需要一个轻量级的服务来方便延迟任务执行并确保只有一个线程用于该工作时,它非常有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接