code: @Override
    public void registerListener(LifecycleListener listener)
    {
      if(listener == null)
        throw new NullPointerException("listener is null");
  
      synchronized(_lock)
      {
        if(_listeners == null || !_listeners.contains(listener))
        {
          Set<LifecycleListener> listeners = new HashSet<LifecycleListener>();
          if(_listeners != null)
            listeners.addAll(_listeners);
          listeners.add(listener);
          _listeners = Collections.unmodifiableSet(listeners);
  
          if(_stateChangeDispatcher == null)
          {
            _stateChangeDispatcher = new StateChangeDispatcher();
            _stateChangeDispatcher.setDaemon(true);
            _stateChangeDispatcher.start();
          }
  
          if(_state == State.CONNECTED)
          {
            // since the listener is new and the client is already connected, we need to send
            // the connected event to this listener!
            _stateChangeDispatcher.addEvent(Arrays.asList(listener),
                                            null,
                                            State.CONNECTED);
          }
        }
      }
    }
docs: When the listener is set, it will receive the {@link LifecycleListener#onConnected()} callback
  right away if ZooKeeper is already connected. This guarantees that you will never miss the
  connected event irrelevant of whether you set the listener before or after calling
  {@link #start()}.