当状态开始时,番石榴服务停止

时间:2012-08-31 15:54:29

标签: java service guava

我们有几项服务需要一段时间才能启动(1-2分钟)。在此过程中,有人可能会请求强制关闭服务(即转换STARTING -> STOPPING)。查看AbstractService类的来源,我发现在当前状态doStop()STARTING时没有调用NEW,这意味着当停止请求时不通知基础类收到了。

  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是个好主意吗?

1 个答案:

答案 0 :(得分:4)

状态为doStopNEW时,STARTING无法呼叫,因为您不必停止从未启动过的服务。这并不意味着在收到停止请求时不会通知基础类。参考the source for stop(),如果状态为NEW,则调用terminated,这会使侦听器排队以调用其terminated方法。类似地,如果状态为STARTING,则调用stopping,这会使侦听器排队以调用其stopping方法。然后finally中的stop阻止调用executeListeners来执行任何排队Listener

简而言之,是的,使用Service.Listener是个好主意。请务必在启动之前将Listener添加到Service,这样您就不会错过任何状态转换的通知。 failedstoppingterminated方法都会获得Service.State传递给他们的Service,因此您可以将清理代码放入正常情况的Listener terminated方法(Service得到RUNNING的方法),在if (from == STARTING)方法的stopping块中您描述了在启动期间强制关闭的位置,以及failed方法中的特殊情况。