使用Guava的可重启服务

时间:2012-01-23 18:03:30

标签: java guava

我正在开发一个应用程序,我需要管理多个服务的状态,并根据某些事件停止/启动它们。问题是,正如文档中所述,Guava的服务是单向的,这意味着,一旦停止,它就无法再次启动。

由于我需要以某种方式解决这个问题,我面临着一些替代方案,我想提出来考虑(特别是因为我现在还不知道每一个都有缺点) )。

这个问题的第一个明显的解决方案是在我需要“重启”它时实例化一个新服务。这是有效的,但在我目前的架构中,它会使事情变得复杂:目前我正在设置所有服务,并基于EventBus的事件,如果需要启动或停止它们。调用start和stop方法的类仅保存对Map of Services的引用,并根据收到的Event在这些实例上调用正确的方法。如果我需要实例化一个新对象以响应一个事件,我将不得不放弃我目前拥有的一些解耦(可能通过保留每种类型的服务的类并使用反射来调用构造函数)。 / p>

另一种可能性是将Service接口实现为RestartableThreadedService(或沿着这些行)。如果我采用这种方法,我的start()方法可以创建另一个Thread,就像它是第一次一样,并重置状态。

第二种方法有明显的缺点吗?我担心我可能会遗漏一些明显的缺点(除了必须编写更复杂的代码),特别是在线程管理方面。

3 个答案:

答案 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();
    }
}