AOSP并发编程案例之ConditionVariable

packages/modules/Connectivity/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java

static class NetworkInterfaceState {
    ...
    private @Nullable EthernetIpClientCallback mIpClientCallback;
    ...
    private class EthernetIpClientCallback extends IpClientCallbacks {
        private final ConditionVariable mIpClientStartCv = new ConditionVariable(false);
        private final ConditionVariable mIpClientShutdownCv = new ConditionVariable(false);

        @Override
        public void onIpClientCreated(IIpClient ipClient) {
            mIpClient = mDeps.makeIpClientManager(ipClient);
            mIpClientStartCv.open();
        }

        private void awaitIpClientStart() {
            mIpClientStartCv.block();
        }

        private void awaitIpClientShutdown() {
            mIpClientShutdownCv.block();
        }

        private boolean isCurrentCallback() {
            return this == mIpClientCallback;
        }

        private void handleIpEvent(final @NonNull Runnable r) {
                mHandler.post(() -> {
                    if (!isCurrentCallback()) {
                        Log.i(TAG, "Ignoring stale IpClientCallbacks " + this);
                        return;
                    }
                    r.run();
                });
            }

        @Override
        public void onProvisioningSuccess(LinkProperties newLp) {
            handleIpEvent(() -> onIpLayerStarted(newLp));
        }

        @Override
        public void onProvisioningFailure(LinkProperties newLp) {
            handleIpEvent(() -> onIpLayerStopped());
        }

        @Override
        public void onLinkPropertiesChange(LinkProperties newLp) {
            handleIpEvent(() -> updateLinkProperties(newLp));
        }

        @Override
        public void onReachabilityLost(String logMsg) {
            handleIpEvent(() -> updateNeighborLostEvent(logMsg));
        }

        @Override
        public void onQuit() {
            mIpClient = null;
            mIpClientShutdownCv.open();
        }
    }
    ...
    private void start() {
        if (mIpClient != null) {
            if (DBG) Log.d(TAG, "IpClient already started");
            return;
        }
        ...
        mIpClientCallback = new EthernetIpClientCallback();
        mDeps.makeIpClient(mContext, name, mIpClientCallback);
        mIpClientCallback.awaitIpClientStart();
        ...
        mIpClient.startProvisioning(createProvisioningConfiguration(mIpConfig));
    }
    ...
    private void stop() {
        if (mNetworkAgent != null) {
            mNetworkAgent.unregister();
            mNetworkAgent = null;
        }

        // Invalidate all previous start requests
        if (mIpClient != null) {
            mIpClient.shutdown();
            mIpClientCallback.awaitIpClientShutdown();
            mIpClient = null;
        }

        mIpClientCallback = null;

        mLinkProperties.clear();
    }
    ....
}