携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第10天,点击查看活动详情
线程池使用get(long timeout,TimeUnit unit)方法
方法get(long timeout,TimeUnit unit)的作用是在指定的最大时间内等待获取返回值。
线程执行代码如下:
@Slf4j
public class FourthCallable implements Callable<String> {
@Override
public String call() throws Exception {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
Thread.sleep(10000);
log.info("休眠 10秒执行完毕");
return simpleDateFormat.format(new Date());
}
}
运行类代码如下:
@Slf4j
public class LimitedAcquisitionTimeRun {
public static void main(String[] args) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
FourthCallable fourthCallable = new FourthCallable();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 3, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
log.info("开始时间:{}",simpleDateFormat.format(new Date()));
Future<String> future = threadPoolExecutor.submit(fourthCallable);
try {
log.info("返回值:{}",future.get(5,TimeUnit.SECONDS));
log.info("结束时间:{}",simpleDateFormat.format(new Date()));
} catch (InterruptedException e) {
log.error("进入 捕获InterruptedException异常");
e.printStackTrace();
} catch (ExecutionException e) {
log.error("进入 捕获ExecutionException异常");
e.printStackTrace();
} catch (TimeoutException e) {
log.error("进入 捕获TimeoutException异常");
e.printStackTrace();
}
}
}
运行结果如下:
16:23:25.241 [main] INFO com.ozx.concurrentprogram.executor.controller.LimitedAcquisitionTimeRun - 开始时间:16:23:25
16:23:30.314 [main] ERROR com.ozx.concurrentprogram.executor.controller.LimitedAcquisitionTimeRun - 进入 捕获TimeoutException异常
java.util.concurrent.TimeoutException at java.util.concurrent.FutureTask.get(FutureTask.java:205) at com.ozx.concurrentprogram.executor.controller.LimitedAcquisitionTimeRun.main(LimitedAcquisitionTimeRun.java:24)
16:23:35.310 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.service.FourthCallable - 休眠 10秒执行完毕
从运行结果看来程序超时后出现异常,进入捕获TimeoutException异常
异常的处理
接口Callable任务在执行时有可能会出现异常,那在Callable中异常是怎样处理呢?
线程执行代码如下:
@Slf4j
public class FourthCallable implements Callable<String> {
private String name;
public FourthCallable(String name){
super();
this.name=name;
}
@Override
public String call() throws Exception {
Integer.parseInt("a");
return "返回值:"+name;
}
}
运行类代码如下:
@Slf4j
public class ExceptionRun {
public static void main(String[] args) {
FourthCallable fourthCallable = new FourthCallable("Gxin");
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 3, 20, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
Future<String> future = threadPoolExecutor.submit(fourthCallable);
try {
String result = future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
log.error("线程代码出现错误");
e.printStackTrace();
}
}
}
运行结果如下:
17:19:27.277 [main] ERROR com.ozx.concurrentprogram.executor.controller.ExceptionRun - 线程代码出现错误
java.util.concurrent.ExecutionException: java.lang.NumberFormatException: For input string: "a" at java.util.concurrent.FutureTask.report(FutureTask.java:122) at java.util.concurrent.FutureTask.get(FutureTask.java:192) at com.ozx.concurrentprogram.executor.controller.ExceptionRun.main(ExceptionRun.java:20)
Caused by: java.lang.NumberFormatException: For input string: "a" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) at java.lang.Integer.parseInt(Integer.java:580) at java.lang.Integer.parseInt(Integer.java:615) at com.ozx.concurrentprogram.executor.service.FourthCallable.call(FourthCallable.java:30) at com.ozx.concurrentprogram.executor.service.FourthCallable.call(FourthCallable.java:14) at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266) at java.util.concurrent.FutureTask.run(FutureTask.java) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)
从运行结果看出线程执行出现错误,异常被捕获到了,出现异常就进入了catch语句,不再继续执行get()方法获取返回值结果,这情况与通过for循环调用get()方法时的效果是一样的,不再继续执行for循环,而是直接进入catch捕获异常代码块。