1、说明
java已经为我们提供了解决办法。jdk1.5带来的并发库future类可以满足这一需求。future类中重要的方法有get()和cancel()。get()获取数据对象,如果数据没有加载,则在获取数据之前堵塞,cancel()取消数据加载。另一个get(timeout)操作表明,如果timeout时间内没有得到,就会失败回来,不会堵塞。
利用泛型和函数式接口编写一个工具类,可以让超时处理更方便,而不用到处写代码。
2、实例
/** * timeoututil <br> * * @author lys * @date 2021/2/25 */@slf4j@component@noargsconstructorpublic 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); } } }
以上就是怎么使用java编写超时工具类的详细内容。