CompletableFuture超时处理
⼀,超时⼯具类
deduck.sftp;
import urrent.*;
import java.util.function.Function;
/**
* java8中CompletableFuture异步处理超时的⽅法
*
* Java 8 的 CompletableFuture 并没有 timeout 机制,虽然可以在 get 的时候指定 timeout,是⼀个同步堵塞的操作。怎样让 timeout 也是异步的呢?Java 8 内有内建的机
*  制⽀持,⼀般的实现⽅案是启动⼀个 ScheduledThreadpoolExecutor 线程在 timeout 时间后直接调⽤ CompletableFuturepleteExceptionally(new TimeoutException()), *  然后⽤acceptEither() 或者 ap
plyToEither 看是先计算完成还是先超时:
*
*  在 java 9 引⼊了 orTimeout 和 completeOnTimeOut 两个⽅法⽀持异步 timeout 机制:
*
* public CompletableFuture orTimeout(long timeout, TimeUnit unit) : completes the CompletableFuture with a TimeoutException after the specified timeout has elapsed.
* public CompletableFuture completeOnTimeout(T value, long timeout, TimeUnit unit) : provides a default value in the case that the CompletableFuture pipeline times out. * 内部实现上跟我们上⾯的实现⽅案是⼀模⼀样的,只是现在不需要⾃⼰实现了。
*
* 实际上hystrix等熔断的框架,其实现线程Timeout之后就关闭线程,也是基于同样的道理,所以我们可以看到hystrix中会有⼀个Timer Thread
*
*
timeout on t2 timer* @author luliang
* @date 2021-02-24 9:48
*/
public class CompletableFutureTimeout {
/**
* Singleton delay scheduler, used only for starting and * cancelling tasks.
*/
static final class Delayer {
static ScheduledFuture<?> delay(Runnable command, long delay, TimeUnit unit) {
return delayer.schedule(command, delay, unit);
}
static final class DaemonThreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
t.setName("CompletableFutureDelayScheduler");
return t;
}
}
static final ScheduledThreadPoolExecutor delayer;
/
/ 注意,这⾥使⽤⼀个线程就可以搞定因为这个线程并不真的执⾏请求⽽是仅仅抛出⼀个异常
static {
delayer = new ScheduledThreadPoolExecutor(1, new CompletableFutureTimeout.Delayer.DaemonThreadFactory());
delayer.setRemoveOnCancelPolicy(true);
}
}
public static <T> CompletableFuture<T> timeoutAfter(long timeout, TimeUnit unit) {
CompletableFuture<T> result = new CompletableFuture<T>();
// timeout 时间后抛出TimeoutException 类似于sentinel / watcher
CompletableFutureTimeout.Delayer.delayer.schedule(() -> resultpleteExceptionally(new TimeoutException()), timeout, unit);
return result;
}
/**
* 哪个先完成就apply哪⼀个结果这是⼀个关键的API,exceptionally出现异常后返回默认值
*
* @param t
* @param future
* @param timeout
* @param unit

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。