怎么使用Java编写超时工具类

2023-05-16 0 4,740

1、说明

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

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

2、实例

/**
 * TimeoutUtil <br>
 *
 * @author lys
 * @date 2021/2/25
 */
@Slf4j
@Component
@NoArgsConstructor
public class TimeoutUtil {
 
    private ExecutorService executorService;
 
    public TimeoutUtil(ExecutorService executorService) {
        this.executorService = executorService;
    }
 
    /**
     * 有超时限制的方法
     *
     * @param bizSupplier 业务函数
     * @param timeout     超时时间,ms
     * @return 返回值
     */
    public <R> Result<R> doWithTimeLimit(Supplier<R> bizSupplier, int timeout) {
        return doWithTimeLimit(bizSupplier, null, timeout);
    }
 
    /**
     * 有超时限制的方法
     *
     * @param bizSupplier   业务函数
     * @param defaultResult 默认值
     * @param timeout       超时时间,ms
     * @return 返回值
     */
    public <R> Result<R> doWithTimeLimit(Supplier<R> bizSupplier, R defaultResult, int timeout) {
 
        R result;
        String errMsg = "Null value";
        FutureTask<R> futureTask = new FutureTask<>(bizSupplier::get);
        executorService.execute(futureTask);
        try {
            result = futureTask.get(timeout, TimeUnit.MILLISECONDS);
        } catch (InterruptedException | ExecutionException | TimeoutException e) {
            errMsg = String.format("doWithTimeLimit执行超过%d毫秒,强制结束", timeout);
            log.error(errMsg, e);
            futureTask.cancel(true);
            result = defaultResult;
        }
        return of(result, errMsg);
    }
 
    /**
     * 随机耗时的测试方法
     */
    private String randomSpentTime() {
        Random random = new Random();
        int time = (random.nextInt(10) + 1) * 1000;
        log.info("预计randomSpentTime方法执行将耗时: " + time + "毫秒");
        try {
            Thread.sleep(time);
        } catch (Exception e) {
        }
        return "randomSpentTime --> " + time;
    }
 
    public static void main(String[] args) throws Exception {
        ExecutorService executorService = new ThreadPoolExecutor(1, 1,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>(),
                runnable -> {
                    Thread thread = new Thread(runnable);
                    // 以守护线程方式启动
                    thread.setDaemon(true);
                    return thread;
                });
        TimeoutUtil timeoutUtil = new TimeoutUtil(executorService);
        for (int i = 1; i <= 10; i++) {
            log.info("\\n=============第{}次超时测试=============", i);
            Thread.sleep(6000);
            long start = System.currentTimeMillis();
            String result = timeoutUtil.doWithTimeLimit(() -> timeoutUtil.randomSpentTime(), 5000).getOrElse("默认");
            log.info("doWithTimeLimit方法实际耗时{}毫秒,结果:{}", System.currentTimeMillis() - start, result);
        }
    }
 
}
资源下载此资源下载价格为1小猪币,终身VIP免费,请先
由于本站资源来源于互联网,以研究交流为目的,所有仅供大家参考、学习,不存在任何商业目的与商业用途,如资源存在BUG以及其他任何问题,请自行解决,本站不提供技术服务! 由于资源为虚拟可复制性,下载后不予退积分和退款,谢谢您的支持!如遇到失效或错误的下载链接请联系客服QQ:442469558

:本文采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可, 转载请附上原文出处链接。
1、本站提供的源码不保证资源的完整性以及安全性,不附带任何技术服务!
2、本站提供的模板、软件工具等其他资源,均不包含技术服务,请大家谅解!
3、本站提供的资源仅供下载者参考学习,请勿用于任何商业用途,请24小时内删除!
4、如需商用,请购买正版,由于未及时购买正版发生的侵权行为,与本站无关。
5、本站部分资源存放于百度网盘或其他网盘中,请提前注册好百度网盘账号,下载安装百度网盘客户端或其他网盘客户端进行下载;
6、本站部分资源文件是经压缩后的,请下载后安装解压软件,推荐使用WinRAR和7-Zip解压软件。
7、如果本站提供的资源侵犯到了您的权益,请邮件联系: 442469558@qq.com 进行处理!

猪小侠源码-最新源码下载平台 Java教程 怎么使用Java编写超时工具类 http://www.20zxx.cn/704801/xuexijiaocheng/javajc.html

猪小侠源码,优质资源分享网

常见问题
  • 本站所有资源版权均属于原作者所有,均只能用于参考学习,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担
查看详情
  • 最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,建议提前注册好百度网盘账号,使用百度网盘客户端下载
查看详情

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务