@@ -0,0 +1,1756 @@
+package com.github.phantomthief.concurrent;%0A%0Aimport static org.slf4j.LoggerFactory.getLogger;%0A%0Aimport java.util.ArrayList;%0Aimport java.util.List;%0Aimport java.util.concurrent.ExecutionException;%0Aimport java.util.concurrent.TimeUnit;%0Aimport java.util.concurrent.TimeoutException;%0A%0Aimport org.slf4j.Logger;%0A%0Aimport com.github.phantomthief.util.ThrowableRunnable;%0Aimport com.google.common.util.concurrent.ForwardingListenableFuture;%0Aimport com.google.common.util.concurrent.ListenableFuture;%0A%0A/**%0A * @author w.vela%0A * Created on 16/5/31.%0A */%0Apublic class TimeoutListenableFuture%3CV%3E extends ForwardingListenableFuture%3CV%3E %7B%0A%0A    private static final Logger logger = getLogger(TimeoutListenableFuture.class);%0A%0A    private final ListenableFuture%3CV%3E delegate;%0A    private final List%3CThrowableRunnable%3CException%3E%3E timeoutListeners = new ArrayList%3C%3E();%0A%0A    public TimeoutListenableFuture(ListenableFuture%3CV%3E delegate) %7B%0A        this.delegate = delegate;%0A    %7D%0A%0A    @Override%0A    protected ListenableFuture%3CV%3E delegate() %7B%0A        return delegate;%0A    %7D%0A%0A    public TimeoutListenableFuture%3CV%3E addTimeoutListener(ThrowableRunnable%3CException%3E consumer) %7B%0A        timeoutListeners.add(consumer);%0A        return this;%0A    %7D%0A%0A    @Override%0A    public V get(long timeout, TimeUnit unit)%0A            throws InterruptedException, ExecutionException, TimeoutException %7B%0A        try %7B%0A            return delegate().get(timeout, unit);%0A        %7D catch (TimeoutException e) %7B%0A            for (ThrowableRunnable%3CException%3E timeoutListener : timeoutListeners) %7B%0A                try %7B%0A                    timeoutListener.run();%0A                %7D catch (Exception e1) %7B%0A                    logger.error(%22%22, e1);%0A                %7D%0A            %7D%0A            throw e;%0A        %7D%0A    %7D%0A%7D%0A

add TimeoutListenableFuture.