我正在开发一个应用程序,我需要管理多个服务的状态,并根据某些事件停止/启动它们。问题是,正如文档中所述,Guava的服务是单向的,这意味着,一旦停止,它就无法再次启动。
由于我需要以某种方式解决这个问题,我面临着一些替代方案,我想提出来考虑(特别是因为我现在还不知道每一个都有缺点) )。
这个问题的第一个明显的解决方案是在我需要“重启”它时实例化一个新服务。这是有效的,但在我目前的架构中,它会使事情变得复杂:目前我正在设置所有服务,并基于EventBus的事件,如果需要启动或停止它们。调用start和stop方法的类仅保存对Map of Services的引用,并根据收到的Event在这些实例上调用正确的方法。如果我需要实例化一个新对象以响应一个事件,我将不得不放弃我目前拥有的一些解耦(可能通过保留每种类型的服务的类并使用反射来调用构造函数)。 / p>
另一种可能性是将Service接口实现为RestartableThreadedService(或沿着这些行)。如果我采用这种方法,我的start()方法可以创建另一个Thread,就像它是第一次一样,并重置状态。
第二种方法有明显的缺点吗?我担心我可能会遗漏一些明显的缺点(除了必须编写更复杂的代码),特别是在线程管理方面。
答案 0 :(得分:3)
我建议你采用第一种方法,但有更好的方法来做反应。使用依赖注入,或者可能传递Supplier<Service>
个对象而不是使用serviceClass.newInstance()
,可能就是这里的方法。
答案 1 :(得分:1)
考虑使用Guice的范围。
答案 2 :(得分:1)
在此github中跟踪相同的问题:https://github.com/google/guava/issues/418
我在这里有一个建议的更改:https://github.com/okigan/guava/commit/8f51b155f9ce5c60236b9a9bfdc6ca5f8bf5e51d
它的要点是向AbstractService添加一个reset() 允许从TERMINATED转换回NEW:
public final void reset() {
lock.lock();
try {
switch (snapshot.state) {
case TERMINATED:
case FAILED:
snapshot = new StateSnapshot(State.NEW);
break;
default:
throw new AssertionError("Unexpected state: " + snapshot.state);
}
} catch (Throwable resetFailure) {
notifyFailed(resetFailure);
} finally {
lock.unlock();
executeListeners();
}
}