7

请有人告诉我一个真实的例子,在哪里使用这种工厂方法而不是其他方法更方便?

新单线程执行器

公共静态 ExecutorService newSingleThreadExecutor()

创建一个使用单个工作线程在无界队列上运行的 Executor。(但请注意,如果该单线程在关闭前的执行过程中因失败而终止,则如果需要执行后续任务,则新线程将取代它。)任务保证按顺序执行,并且不会有多个任务处于活动状态在任何给定时间。与其他等效的 newFixedThreadPool(1) 不同,返回的执行程序保证不可重新配置以使用额外的线程。

提前致谢。

4

4 回答 4

14

请有人告诉我一个现实生活中的例子,使用[newSingleThreadExecutor()工厂方法]而不是其他方法更方便?

我假设您询问何时使用单线程线程池而不是固定或缓存线程池。

当我有许多任务要运行但我只想要一个线程来执行它时,我使用单线程执行器。这当然和使用 1 的固定线程池是一样的。这通常是因为我们不需要它们并行运行,它们是后台任务,我们不想占用太多系统资源(CPU、内存、IO)。Callable我想以对象或Runnable对象的形式处理各种任务,所以这ExecutorService是最佳的,但我只需要一个线程来运行它们。

例如,我有许多我弹簧注入的计时器任务。我有两种任务,我的“短期”任务在单个线程池中运行。即使我的系统中有几百个线程,也只有一个线程可以执行它们。他们执行日常任务,例如检查磁盘空间、清理日志、转储统计信息等。对于时间紧迫的任务,我在缓存线程池中运行。

另一个例子是我们有一系列合作伙伴集成任务。它们不需要很长时间,而且运行频率很低,我们不希望它们与其他系统线程竞争,因此它们在单线程执行器中运行。

第三个例子是我们有一个有限状态机,其中每个状态修改器将作业从一个状态转移到另一个状态,并Runnable在单个线程池中注册为 a。尽管我们有数百个 mutator,但在任何一个时间点只有一个任务是有效的,因此为该任务分配多个线程是没有意义的。

于 2013-05-29T13:00:40.823 回答
3

除了已经提到的原因之外,当您需要排序保证时,您可能希望使用单线程执行程序,即您需要确保提交的任何任务将始终按照提交的顺序发生。

于 2014-06-20T07:04:19.383 回答
2

Executors.newSingleThreadExecutor()和之间的差异Executors.newFixedThreadPool(1)很小,但在设计库 API 时会有所帮助。如果您将返回的内容暴露ExecutorService给您的库的用户,并且该库仅在执行程序使用单个线程(任务不是线程安全的)时才能正常工作,则最好使用Executors.newSingleThreadExecutor(). 否则,您的图书馆的用户可能会通过这样做来破坏它:

ExecutorService e = myLibrary.getBackgroundTaskExecutor();
((ThreadPoolExecutor)e).setCorePoolSize(10);

,这是不可能的Executors.newSingleThreadExecutor()

于 2013-05-29T14:35:45.137 回答
0

当您需要一个轻量级服务时,它会很有帮助,它只方便延迟任务执行,并且您希望确保只有一个线程用于该作业。

于 2013-05-29T13:01:19.863 回答