我们有几个服务需要一段时间才能启动(1-2 分钟)。在此过程中,有人可能会请求强制关闭服务(即转换 STARTING -> STOPPING
)。查看 AbstractService 的来源class 我看到当当前状态为 STARTING
或 NEW
时没有调用 doStop()
这意味着在停止时不会通知基础类收到请求。
switch (snapshot.state) {
case NEW:
snapshot = new StateSnapshot(State.TERMINATED);
terminated(State.NEW);
break;
case STARTING:
snapshot = new StateSnapshot(State.STARTING, true, null);
stopping(State.STARTING);
break;
case RUNNING:
snapshot = new StateSnapshot(State.STOPPING);
stopping(State.RUNNING);
doStop();
break;
case STOPPING:
case TERMINATED:
case FAILED:
// do nothing
break;
default:
throw new AssertionError("Unexpected state: " + snapshot.state);
}
由于无论状态如何我都需要执行一些清理,有没有办法获得有关关机的通知?使用 Service.Listener 是个好主意吗?在子类中?
最佳答案
当状态为 NEW
或 STARTING
时,不会调用 doStop
,因为您不必停止从未启动的服务.这并不意味着在收到停止请求时不会通知基础类。引用the source for stop()
,如果状态为 NEW
,则调用 terminated
,这会将监听器排队以调用其 terminated
方法。类似地,如果状态为 STARTING
,则会调用 stopping
,这会使监听器排队等待调用它们的 stopping
方法。然后 stop
中的 finally
block 调用 executeListeners
来执行任何排队的 Listener
。
简而言之,是的,使用 Service.Listener
是个好主意。确保在启动之前将 Listener
添加到 Service
中,这样您就不会错过任何状态转换的通知。 failed
、stopping
和terminated
方法都获取Service.State
Service
已传递给他们,因此您可以在 Listener
的 terminated
方法中为正常情况(其中 Service
gets RUNNING
), inside an if (from == STARTING)
block in your stopping
对于你描述的你想要强制执行的情况在启动期间关闭,以及在异常情况下的 failed
方法中。
关于java - Guava 服务在状态为 STARTING 时停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12218793/