class LatchObject {
        final CountDownLatch latch;

        public LatchObject(CountDownLatch latch) {
            this.latch = latch;
        }
    }

    public ConcurrentAsyncCallback() {
    }

    @Override
    public void setDbException(DbException e, boolean cancel) {
        setAsyncResult(e);
        if (cancel)
            countDown();
    }

    @Override
    public final void run(NetInputStream in) {
        // 放在最前面，不能放在最后面，
        // 否则调用了countDown，但是在设置runEnd为true前，调用await的线程读到的是false就会抛异常
        runEnd = true;
        // if (asyncResult == null) {
        try {
            runInternal(in);
        } catch (Throwable t) {
            setAsyncResult(t);
        }
        // }
    }

    @Override
    protected T await(long timeoutMillis) {<FILL_FUNCTION_BODY>

        Scheduler scheduler = SchedulerThread.currentScheduler();
        if (scheduler != null)
            scheduler.executeNextStatement();
        if (latchObjectRef.compareAndSet(null, new LatchObject(new CountDownLatch(1)))) {
            CountDownLatch latch = latchObjectRef.get().latch;
            try {
                if (timeoutMillis > 0)
                    latch.await(timeoutMillis, TimeUnit.MILLISECONDS);
                else
                    latch.await();
                if (asyncResult != null && asyncResult.isFailed())
                    throw DbException.convert(asyncResult.getCause());

                // 如果没有执行过run，抛出合适的异常
                if (!runEnd) {
                    handleTimeout();
                }
            } catch (InterruptedException e) {
                throw DbException.convert(e);
            }
            if (asyncResult != null)
                return asyncResult.getResult();
            else
                return null;
        } else {
            if (asyncResult.isFailed())
                throw DbException.convert(asyncResult.getCause());
            else
                return asyncResult.getResult();
        }
    
<methods>public void <init>() ,public void checkTimeout(long) ,public static AsyncCallback<T> create(boolean) ,public static AsyncCallback<T> createConcurrentCallback() ,public static AsyncCallback<T> createSingleThreadCallback() ,public T get() ,public T get(long) ,public int getNetworkTimeout() ,public long getStartTime() ,public Future<T> onComplete(AsyncHandler<AsyncResult<T>>) ,public Future<T> onFailure(AsyncHandler<java.lang.Throwable>) ,public Future<T> onSuccess(AsyncHandler<T>) ,public void run(com.lealone.net.NetInputStream) ,public void setAsyncResult(java.lang.Throwable) ,public void setAsyncResult(T) ,public void setAsyncResult(AsyncResult<T>) ,public void setDbException(com.lealone.common.exceptions.DbException, boolean) ,public void setNetworkTimeout(int) ,public void setPacket(com.lealone.server.protocol.Packet) ,public void setStartTime(long) <variables>private int networkTimeout,private com.lealone.server.protocol.Packet packet,private long startTime