携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第24天,点击查看活动详情
ExecutorService的方法invokeAny与异常处理
运行类代码如下:
public class InvokeAnyRun {
public static void main(String[] args) {
List list = new ArrayList();
list.add(new FCallable());
list.add(new SCallable());
ExecutorService executorService = Executors.newCachedThreadPool();
try {
String result = (String) executorService.invokeAny(list);
System.out.println("已完成任务的返回值:"+result);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
运行结果如下:
com.ozx.concurrentprogram.executor.service.SCallable 开始时间: 1660900886381
com.ozx.concurrentprogram.executor.service.FCallable 开始时间: 1660900886381
com.ozx.concurrentprogram.executor.service.SCallable 结束时间: 1660900886384
com.ozx.concurrentprogram.executor.service.FCallable 结束时间: 1660900886386
已完成任务的返回值:com.ozx.concurrentprogram.executor.service.SCallable
从运行结果看来虽然方法invokeAny()已经获取的第二个线程的返回值,但是第一个线程正在继续运行中,直到运行完毕。
修改运行类执行代码如下:
public class InvokeAnyRun {
public static void main(String[] args) {
List list = new ArrayList();
list.add(new FCallable());
list.add(new TCallable());
ExecutorService executorService = Executors.newCachedThreadPool();
try {
String result = (String) executorService.invokeAny(list);
System.out.println("已完成任务的返回值:"+result);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
运行结果如下:
com.ozx.concurrentprogram.executor.service.TCallable 开始时间: 1660902186975
com.ozx.concurrentprogram.executor.service.FCallable 开始时间: 1660902186975
com.ozx.concurrentprogram.executor.service.FCallable 结束时间: 1660902186978
com.ozx.concurrentprogram.executor.service.TCallable 抛出异常中断......
已完成任务的返回值:com.ozx.concurrentprogram.executor.service.FCallable
从运行结果看出第一个线程执行完毕后,线程池将第三个线程设置为interrupt状态,而第三个线程可以自定义对中断interrupt状态进行处理,就是说可以决定是否使用Thread.currentThread().isInterrupted()结合throw new
InterruptedException()的代码。
如果使用Thread.currentThread().isInterrupted()结合throw new InterruptedException()的代码说明对第三个线程进行中断的意图更加明确。
方法InvokeAny()与执行慢的任务异常
执行时间短的任务优先执行完毕后,执行时间长的任务出现异常时,默认情况下不会在控制台输出异常信息,如果显式使用try-catch语句块则可以自定义捕获异常。