@Override
 public final synchronized void start(Listener listener) {
   Preconditions.checkState(this.listener == null, "already started");
   timerService = SharedResourceHolder.get(timerServiceResource);
   executor = SharedResourceHolder.get(executorResource);
   this.listener = Preconditions.checkNotNull(listener, "listener");
   resolve();
 }
 @Override
 public final synchronized void shutdown() {
   if (shutdown) {
     return;
   }
   shutdown = true;
   if (resolutionTask != null) {
     resolutionTask.cancel(false);
   }
   if (timerService != null) {
     timerService = SharedResourceHolder.release(timerServiceResource, timerService);
   }
   if (executor != null) {
     executor = SharedResourceHolder.release(executorResource, executor);
   }
 }
 /** If we're using the shared executor, returns its reference. */
 private void onChannelTerminated() {
   if (usingSharedExecutor) {
     SharedResourceHolder.release(GrpcUtil.SHARED_CHANNEL_EXECUTOR, (ExecutorService) executor);
   }
   // Release the transport factory so that it can deallocate any resources.
   transportFactory.release();
 }
 /**
  * Initiates an orderly shutdown in which preexisting calls continue but new calls are immediately
  * cancelled.
  */
 @Override
 public ManagedChannelImpl shutdown() {
   ArrayList<TransportSet> transportsCopy = new ArrayList<TransportSet>();
   synchronized (lock) {
     if (shutdown) {
       return this;
     }
     shutdown = true;
     // After shutdown there are no new calls, so no new cancellation tasks are needed
     scheduledExecutor = SharedResourceHolder.release(TIMER_SERVICE, scheduledExecutor);
     if (transports.isEmpty()) {
       terminated = true;
       lock.notifyAll();
       onChannelTerminated();
     } else {
       transportsCopy.addAll(transports.values());
     }
   }
   loadBalancer.shutdown();
   nameResolver.shutdown();
   for (TransportSet ts : transportsCopy) {
     ts.shutdown();
   }
   return this;
 }
  ManagedChannelImpl(
      String target,
      BackoffPolicy.Provider backoffPolicyProvider,
      NameResolver.Factory nameResolverFactory,
      Attributes nameResolverParams,
      LoadBalancer.Factory loadBalancerFactory,
      ClientTransportFactory transportFactory,
      DecompressorRegistry decompressorRegistry,
      CompressorRegistry compressorRegistry,
      @Nullable Executor executor,
      @Nullable String userAgent,
      List<ClientInterceptor> interceptors) {
    if (executor == null) {
      usingSharedExecutor = true;
      this.executor = SharedResourceHolder.get(GrpcUtil.SHARED_CHANNEL_EXECUTOR);
    } else {
      usingSharedExecutor = false;
      this.executor = executor;
    }
    this.backoffPolicyProvider = backoffPolicyProvider;
    this.nameResolver = getNameResolver(target, nameResolverFactory, nameResolverParams);
    this.loadBalancer = loadBalancerFactory.newLoadBalancer(nameResolver.getServiceAuthority(), tm);
    this.transportFactory = transportFactory;
    this.userAgent = userAgent;
    this.interceptorChannel = ClientInterceptors.intercept(new RealChannel(), interceptors);
    scheduledExecutor = SharedResourceHolder.get(TIMER_SERVICE);
    this.decompressorRegistry = decompressorRegistry;
    this.compressorRegistry = compressorRegistry;

    this.nameResolver.start(
        new NameResolver.Listener() {
          @Override
          public void onUpdate(List<ResolvedServerInfo> servers, Attributes config) {
            loadBalancer.handleResolvedAddresses(servers, config);
          }

          @Override
          public void onError(Status error) {
            Preconditions.checkArgument(!error.isOk(), "the error status must not be OK");
            loadBalancer.handleNameResolutionError(error);
          }
        });
  }
 /**
  * Try to get an existing instance of the given resource. If an instance does not exist, create a
  * new one with the given factory.
  *
  * @param resource the singleton object that identifies the requested static resource
  */
 public static <T> T get(Resource<T> resource) {
   return holder.getInternal(resource);
 }
 /**
  * Releases an instance of the given resource.
  *
  * <p>The instance must have been obtained from {@link #get(Resource)}. Otherwise will throw
  * IllegalArgumentException.
  *
  * <p>Caller must not release a reference more than once. It's advisory that you clear the
  * reference to the instance with the null returned by this method.
  *
  * @param resource the singleton Resource object that identifies the released static resource
  * @param instance the released static resource
  * @return a null which the caller can use to clear the reference to that instance.
  */
 public static <T> T release(final Resource<T> resource, final T instance) {
   return holder.releaseInternal(resource, instance);
 }