携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情
ExecutorCompletionService类与异常
使用CompletionService执行任务的过程中不可避免会出现各种情况的异常
线程执行代码如下:
public class ExceptionFirstCallable implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println(super.getClass().getName()+"线程执行开始时间:"+System.currentTimeMillis());
Thread.sleep(5000);
System.out.println(super.getClass().getName() +"线程执行结束时间:"+System.currentTimeMillis());
return super.getClass().getName();
}
}
public class ExceptionSecondCallable implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println(super.getClass().getName()+"线程执行开始时间:"+System.currentTimeMillis());
Thread.sleep(5000);
int i = 0;
if(i == 0){
throw new Exception("抛出异常!");
}
System.out.println(super.getClass().getName() +"线程执行结束时间:"+System.currentTimeMillis());
return super.getClass().getName();
}
}
运行类执行代码如下:
public class ExceptionCallableRun {
public static void main(String[] args) {
try {
ExceptionFirstCallable firstCallable = new ExceptionFirstCallable();
ExceptionSecondCallable secondCallable = new ExceptionSecondCallable();
ExecutorService executorService = Executors.newSingleThreadExecutor();
ExecutorCompletionService executorCompletionService = new ExecutorCompletionService(executorService);
executorCompletionService.submit(firstCallable);
executorCompletionService.submit(secondCallable);
for (int i = 0; i < 2 ; i++) {
System.out.println("休眠中没获取返回值:"+executorCompletionService.take());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行结果如下:
com.ozx.concurrentprogram.executor.service.ExceptionFirstCallable线程执行开始时间:1660554419064
com.ozx.concurrentprogram.executor.service.ExceptionFirstCallable线程执行结束时间:1660554424075
休眠中没获取返回值:java.util.concurrent.FutureTask@3ecf72fd
com.ozx.concurrentprogram.executor.service.ExceptionSecondCallable线程执行开始时间:1660554424077
休眠中没获取返回值:java.util.concurrent.FutureTask@7a92922
从运行结果看出ExceptionSecondCallable执行代码有异常,但是没有调用FutureTask类的get()方法,所以不出现异常。
修改运行类执行代码如下:
public class ExceptionCallableRun {
public static void main(String[] args) {
ExceptionFirstCallable firstCallable = new ExceptionFirstCallable();
ExceptionSecondCallable secondCallable = new ExceptionSecondCallable();
ExecutorService executorService = Executors.newSingleThreadExecutor();
ExecutorCompletionService executorCompletionService = new ExecutorCompletionService(executorService);
executorCompletionService.submit(secondCallable);
executorCompletionService.submit(firstCallable);
for (int i = 0; i < 2 ; i++) {
try {
System.out.println("获取返回值:"+executorCompletionService.take().get());
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
运行结果如下:
com.ozx.concurrentprogram.executor.service.ExceptionSecondCallable 线程执行开始时间:1660633712554
com.ozx.concurrentprogram.executor.service.ExceptionFirstCallable 线程执行开始时间:1660633717565
java.util.concurrent.ExecutionException: java.lang.Exception: 抛出异常!
at java.util.concurrent.FutureTask.report(FutureTask.java:122) at java.util.concurrent.FutureTask.get(FutureTask.java:192) at com.ozx.concurrentprogram.executor.controller.ExceptionCallableRun.main(ExceptionCallableRun.java:29) Caused by: java.lang.Exception: 抛出异常! at com.ozx.concurrentprogram.executor.service.ExceptionSecondCallable.call(ExceptionSecondCallable.java:17) at com.ozx.concurrentprogram.executor.service.ExceptionSecondCallable.call(ExceptionSecondCallable.java:10) at java.util.concurrent.FutureTask.runcapture(FutureTask.java:266) at java.util.concurrent.FutureTask.run(FutureTask.java) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.runcapture(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)
com.ozx.concurrentprogram.executor.service.ExceptionFirstCallable 线程执行结束时间:1660633722573
获取返回值:com.ozx.concurrentprogram.executor.service.ExceptionFirstCallable
看执行过程是先执行有异常的任务,没异常的任务后执行,有异常的任务发生异常时后没有输出返回值,而没异常的任务能通过get()方法获取返回值。