Java编写超时工具类

我们在开发过程中,在进行时间操作时,如果在规定的时间内完成处理的话,有可能会回到正确的结果。否则,就会被视为超时任务。此时,我们不再等待(不再执行)的时间操作,直接向调用者传达这个任务需要时间,被取消了。

1、说明

java已经为我们提供了解决办法。jdk1.5带来的并发库Future类可以满足这一需求。Future类中重要的方法有get()和cancel()。get()获取数据对象,如果数据没有加载,则在获取数据之前堵塞,cancel()取消数据加载。另一个get(timeout)操作表明,如果timeout时间内没有得到,就会失败回来,不会堵塞。

利用泛型和函数式接口编写一个工具类,可以让超时处理更方便,而不用到处写代码。

2、实例

/**
*TimeoutUtil<br>
*
*@authorlys
*@date2021/2/25
*/
@Slf4j
@Component
@NoArgsConstructor
publicclassTimeoutUtil{

privateExecutorServiceexecutorService;

publicTimeoutUtil(ExecutorServiceexecutorService){
this.executorService=executorService;
}

/**
*有超时限制的方法
*
*@parambizSupplier业务函数
*@paramtimeout超时时间,ms
*@return返回值
*/
public<R>Result<R>doWithTimeLimit(Supplier<R>bizSupplier,inttimeout){
returndoWithTimeLimit(bizSupplier,null,timeout);
}

/**
*有超时限制的方法
*
*@parambizSupplier业务函数
*@paramdefaultResult默认值
*@paramtimeout超时时间,ms
*@return返回值
*/
public<R>Result<R>doWithTimeLimit(Supplier<R>bizSupplier,RdefaultResult,inttimeout){

Rresult;
StringerrMsg="Nullvalue";
FutureTask<R>futureTask=newFutureTask<>(bizSupplier::get);
executorService.execute(futureTask);
try{
result=futureTask.get(timeout,TimeUnit.MILLISECONDS);
}catch(InterruptedException|ExecutionException|TimeoutExceptione){
errMsg=String.format("doWithTimeLimit执行超过%d毫秒,强制结束",timeout);
log.error(errMsg,e);
futureTask.cancel(true);
result=defaultResult;
}
returnof(result,errMsg);
}

/**
*随机耗时的测试方法
*/
privateStringrandomSpentTime(){
Randomrandom=newRandom();
inttime=(random.nextInt(10)+1)*1000;
log.info("预计randomSpentTime方法执行将耗时:"+time+"毫秒");
try{
Thread.sleep(time);
}catch(Exceptione){
}
return"randomSpentTime-->"+time;
}

publicstaticvoidmain(String[]args)throwsException{
ExecutorServiceexecutorService=newThreadPoolExecutor(1,1,
0L,TimeUnit.MILLISECONDS,
newLinkedBlockingQueue<Runnable>(),
runnable->{
Threadthread=newThread(runnable);
//以守护线程方式启动
thread.setDaemon(true);
returnthread;
});
TimeoutUtiltimeoutUtil=newTimeoutUtil(executorService);
for(inti=1;i<=10;i++){
log.info("\n=============第{}次超时测试=============",i);
Thread.sleep(6000);
longstart=System.currentTimeMillis();
Stringresult=timeoutUtil.doWithTimeLimit(()->timeoutUtil.randomSpentTime(),5000).getOrElse("默认");
log.info("doWithTimeLimit方法实际耗时{}毫秒,结果:{}",System.currentTimeMillis()-start,result);
}
}

}
原文来自:https://www.py.cn
© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容