在过去的几个小时里,我正在阅读相当多的内容,我根本看不到任何理由(有效理由)在 ExecutorService
上调用 shutdown()
,除非我们有一个庞大的应用程序存储,几十个和几十个不同的执行服务使用了很长时间 .
关闭所做的唯一事情(从我收集的内容)是正常线程完成后所做的事情 . 当普通的Thread完成Runnable(或Callable)的run方法时,它将被传递给Garbage Collection进行收集 . 使用Executor Service,线程将被暂停,不会为垃圾收集打勾 . 为此,需要关机 .
好的,回到我的问题 . 是否有任何理由经常在 ExecutorService
上调用关机,甚至在提交某些任务后立即?我想留下有人正在做的事情,并在调用 awaitTermination()
之后,因为这已经过验证 . 一旦我们这样做,我们必须重新创建一个新的 ExecutorService
,做同样的事情 . 是不是 ExecutorService
重用线程的整个想法?那么为什么要这么快就消灭 ExecutorService
?
简单地创建 ExecutorService
(或者根据你需要的数量而不是一对)是不是一种理性的方式,然后在应用程序运行期间将任务一旦传递给他们,然后在应用程序出口或其他一些重要阶段关闭那些遗嘱执行人?
我想从一些经验丰富的编码员那里回答,他们使用ExecutorServices写了很多异步代码 .
第二个问题,与平台有点小的交易 . 如果你们中的一些人会说每次关闭执行程序都不是最好的主意,并且你在android上编程,你能不能告诉我当你处理不同的事件时你如何处理这些关闭(具体来说 - 当你执行它们时)应用生命周期 .
由于CommonsWare评论,我发布了中立的帖子 . 我真的没有兴趣争论死亡,似乎它在那里领先 . 如果他们愿意分享他们的经验,我只对从经验丰富的开发人员那里了解我的问题感兴趣 . 谢谢 .
4 回答
shutdown()
方法做了一件事:阻止客户端向执行程序服务发送更多工作 . 这意味着除非采取其他操作,否则所有现有任务仍将完成 . 即使对于计划任务也是如此,例如对于ScheduledExecutorService:计划任务的新实例将不会运行 . 这在各种场景中都很有用 .假设您有一个控制台应用程序,它具有运行N个任务的执行程序服务 . 如果用户点击CTRL-C,您希望应用程序可能正常终止 . 它优雅地意味着什么?也许您希望您的应用程序无法向执行程序服务提交更多任务,同时您希望等待现有的N个任务完成 . 您可以使用关闭挂钩作为最后的手段来实现此目的:
此挂钩将关闭服务,这将阻止应用程序提交新任务,并在关闭JVM之前等待所有现有任务完成 . await终止将阻塞5秒,如果服务关闭则返回true . 这是在循环中完成的,这样您就可以确定服务最终会关闭 . 每次都会吞下InterruptedException . 这是关闭在整个应用程序中重用的执行程序服务的最佳方法 .
这段代码绝对是肯定的,你的任务最终会终止,你可能想等待给定的超时,然后退出,放弃正在运行的线程 . 在这种情况下,最后尝试中断正在运行的线程时,在超时后调用
shutdownNow()
是有意义的(shutdownNow()
还会给出一个等待运行的任务列表) . 如果您的任务旨在响应中断,这将正常工作 .另一个有趣的场景是,当您有一个执行定期任务的ScheduledExecutorService时 . 停止周期性任务链的唯一方法是调用
shutdown()
.编辑:我推荐使用关闭挂钩,如上所示:一般情况:它可能容易出错,应该只是最后的手段 . 此外,如果您注册了许多关闭挂钩,它们将运行的顺序是未定义的,这可能是不合需要的 . 我宁愿让应用程序在
InterruptedException
上显式调用shutdown()
.Reason for calling shutdown() on ExecutorService
今天我遇到了一种情况,我必须等到机器准备就绪,然后再启动该机器上的一系列任务 .
我对这台机器进行REST调用,如果我没有收到503(服务器不可用),那么机器就可以处理我的请求了 . 所以,我等到第一次REST调用得到200(成功) .
有多种方法可以实现它,我使用ExecutorService创建一个线程并安排它在每X秒后运行 . 所以,我需要在一个条件下停止这个线程,检查这个......
Second side question, a bit smaller deals with android platform.
如果你能提供更多的背景,也许我可以回答!另外根据我在Android开发方面的经验,你很少需要Threads . 您是在开发一款需要线程性能的游戏还是应用程序?如果没有,在Android中你有其他方法可以解决我上面解释过的问题 . 您可以根据上下文使用TimerTask,AsyncTask或Handlers或Loaders . 这是因为如果UIThread等待很长时间你会知道会发生什么:/
Reference Book
Chaper:14页数:814
是 . 你不应该经常破坏和重新创建
ExecutorService
. 在您需要时(主要是在启动时)初始化ExecutorService
并保持活动直到您完成它 .是 . 在应用程序退出等重要阶段关闭
ExecutorService
是合理的 .假设
ExecutorService
在应用程序中的不同活动之间共享 . 每个活动将在不同的时间间隔暂停/恢复,您仍然需要根据您的申请一个ExecutorService
.而不是在Activity生命周期方法中管理
ExecutorService
的状态,而是将ExecutorService管理(创建/关闭)移动到您的自定义Service .在Service =>
onCreate()
中创建ExecutorService
并在onDestroy()
中正确关闭它建议的关闭方法
ExecutorService
:How to properly shutdown java ExecutorService