public static boolean shutdownAndAwaitTermination(final ManagedChannel mChannel, final long timeoutMillis) {
        if (mChannel == null) {
            return true;
        }
        // disable new tasks from being submitted
        mChannel.shutdown();
        final TimeUnit unit = TimeUnit.MILLISECONDS;
        final long phaseOne = timeoutMillis / 5;
        try {
            // wait a while for existing tasks to terminate
            if (mChannel.awaitTermination(phaseOne, unit)) {
                return true;
            }
            mChannel.shutdownNow();
            // wait a while for tasks to respond to being cancelled
            if (mChannel.awaitTermination(timeoutMillis - phaseOne, unit)) {
                return true;
            }
            LOG.warn("Fail to shutdown managed channel: {}.", mChannel);
        } catch (final InterruptedException e) {
            // (Re-)cancel if current thread also interrupted
            mChannel.shutdownNow();
            // preserve interrupt status
            Thread.currentThread().interrupt();
        }
        return false;
    }
The following method shuts down an {@code ManagedChannel} in two
phases, first by calling {@code shutdown} to reject incoming tasks,
and then calling {@code shutdownNow}, if necessary, to cancel any
lingering tasks.
jraft-extension/rpc-grpc-impl/src/main/java/com/alipay/sofa/jraft/rpc/impl/ManagedChannelHelper.java