Java如何实现任务超时处理
任务超时处理是⽐较常见的需求,⽐如在进⾏⼀些⽐较耗时的操作(如⽹络请求)或者在占⽤⼀些⽐较宝贵的资源(如数据库连接)时,我们通常需要给这些操作设置⼀个超时时间,当执⾏时长超过设置的阈值的时候,就终⽌操作并回收资源。Java中对超时任务的处理有两种⽅式:⼀种是基于异步任务结果的超时获取,⼀种则是使⽤延时任务来终⽌超时操作。下⽂将详细说明。
⼀、基于异步任务结果的超时获取
基于异步任务结果的获取通常是跟线程池⼀起使⽤的,我们向线程池提交任务时会返回⼀个Future对象,在调⽤Future的get⽅法时,可以设置⼀个超时时间,如果超过设置的时间任务还没结束,就抛出异常。接下来看代码:
public class FutureDemo {
static ExecutorService executorService= Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*2); public static void main(String[] args) {
Future public String call() { try { TimeUnit.SECONDS.sleep(10); } catch (InterruptedException e) { System.out.println(\"任务被中断。\"); } return \"OK\"; } }); try { String result = future.get(2, TimeUnit.SECONDS); } catch (InterruptedException |ExecutionException | TimeoutException e) { future.cancel(true); System.out.println(\"任务超时。\"); }finally { System.out.println(\"清理资源。\"); } }} 运⾏代码,输出如下: ⼆、使⽤延时任务来终⽌超时操作 还有⼀种实现任务超时处理的思路是在提交任务之前先设置⼀个定时器,这个定时器会在设置的时间间隔之后去取消任务。当然如果任务在规定的时间内完成了,要记得取消定时器。⾸先来看⼀下我们的⼯作线程: public class RunningTask { private volatile boolean isStop; public void stop(){ this.isStop=true; } public void doing() { int i=1; while (!isStop){ try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { } } System.out.println(\"任务被中断。\"); }} 这个⼯作线程每隔⼀秒钟会去检查下isStop变量,因此我们可以通过isStop变量来取消任务。⾄于取消任务的逻辑我们放在了定时器⾥⾯,代码如下: public class CancelTask implements Runnable { private RunningTask runningTask; public CancelTask(RunningTask runningTask) { this.runningTask = runningTask; } @Override public void run() { runningTask.stop(); }} 可以看到,该定时器的作⽤就是在⼀定的时间之后去中断⼯作线程的运⾏。接下来测试⼀下: public class ScheduleDemo { static ScheduledExecutorService executorService= Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors()*2); public static void main(String[] args) { RunningTask runningTask=new RunningTask(); ScheduledFuture> scheduledFuture = executorService.schedule(new CancelTask(runningTask), 3, TimeUnit.SECONDS); runningTask.doing(); if(!scheduledFuture.isDone()){ scheduledFuture.cancel(true); } }} 运⾏结果如下: 可以看到,任务在超时之后也可以被取消。 因篇幅问题不能全部显示,请点此查看更多更全内容