持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情
方法invokeAll(Collection tasks)快的任务正确执行,慢的任务异常情况
在多个任务的过程中,执行任务快慢与运行时发生的异常也有关联。
第一个线程执行代码如下:
public class OFirstCallable implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println(Thread.currentThread().getName()+ "线程执行开始时间:"+ System.currentTimeMillis());
for (int i = 0; i < 123456; i++) {
Math.random();
Math.random();
Math.random();
System.out.println(Thread.currentThread().getName()+(i+1));
}
System.out.println(Thread.currentThread().getName()+"线程执行结束时间:" + System.currentTimeMillis());
return super.getClass().getName();
}
}
第二个线程执行代码如下:
public class OSecondCallable implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println(Thread.currentThread().getName()+ "线程执行开始时间:"+ System.currentTimeMillis());
for (int i = 0; i < 123456; i++) {
Math.random();
Math.random();
Math.random();
System.out.println(Thread.currentThread().getName()+(i+1));
}
System.out.println(Thread.currentThread().getName()+"线程执行结束时间:" + System.currentTimeMillis());
if(true){
System.out.println(super.getClass().getName()+"报错了");
throw new Exception("发生异常了");
}
return super.getClass().getName();
}
}
运行结果如下:
public class invokeAllRun {
public static void main(String[] args) {
OFirstCallable oFirstCallable = new OFirstCallable();
OSecondCallable oSecondCallable = new OSecondCallable();
List<Callable<String>> list = new ArrayList<>();
list.add(oFirstCallable);
list.add(oSecondCallable);
ExecutorService executorService = Executors.newCachedThreadPool();
System.out.println("invokeAll方法执行开始时间:" + System.currentTimeMillis());
try {
List<Future<String>> futureList = executorService.invokeAll(list);
System.out.println("invokeAll方法执行结束时间: " + System.currentTimeMillis());
for (int i= 0;i< futureList.size();i++) {
System.out.println("返回的结果:" + futureList.get(i).get() + " 返回结果时间: "+ System.currentTimeMillis());
}
System.out.println("主线程结束!");
} catch (InterruptedException e) {
System.out.println("进入 InterruptedException 异常捕获");
e.printStackTrace();
} catch (ExecutionException e) {
System.out.println("进入 ExecutionException 异常捕获");
e.printStackTrace();
}
}
}
运行结果如下:
.....
pool-1-thread-1123453
pool-1-thread-1123454
pool-1-thread-1123455
pool-1-thread-1123456
pool-1-thread-1线程执行结束时间:1664595679054 invokeAll方法执行结束时间: 1664595679055
返回的结果:com.ozx.concurrentprogram.executor.service.october.OFirstCallable 返回结果时间: 1664595679055
进入 ExecutionException 异常捕获
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.october.invokeAllRun.main(invokeAllRun.java:28)
Caused by: java.lang.Exception: 发生异常了 at com.ozx.concurrentprogram.executor.service.october.OSecondCallable.call(OSecondCallable.java:24) at com.ozx.concurrentprogram.executor.service.october.OSecondCallable.call(OSecondCallable.java:10) 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)
从运行结果看出在控制台输出“发生异常了”字符串,说明了invokeAll()方法对Callable抛出去的异常是可以处理的,由于在main()方法中直接进入了catch捕获语句块,所以导致字符串主线程结束也没被输出来。