携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第30天,点击查看活动详情
方法invokeAny(Collection Tasks,timeout,timeUnit)超时设置
运行类执行代码如下:
public class InvokeAnyRun {
public static void main(String[] args) {
try {
List list = new ArrayList();
list.add(new FCallable());
// list.add(new SCallable());
ExecutorService executorService = Executors.newCachedThreadPool();
String result = (String) executorService.invokeAny(list,1, TimeUnit.SECONDS);
System.out.println("已完成任务的返回值:"+result);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("进入捕获到 InterruptedException");
} catch (ExecutionException e) {
e.printStackTrace();
System.out.println("进入捕获到 ExecutionException");
} catch (TimeoutException e) {
e.printStackTrace();
System.out.println("进入捕获到 TimeoutException");
}
}
}
运行结果如下:
FCallable i:1234566
FCallable i:1234567
com.ozx.concurrentprogram.executor.service.FCallable 结束时间: 1661589890529
在出现超时异常时,可以使用if(Thread.currentThread().isInterrupted() == true)判断和throw new InterruptedException()结合使用线程中断执行。
如果只有一个任务被执行,这个任务既超时又出现了异常,运行情况如下:
线程执行代码如下:
public class FCallable implements Callable<String> {
@Override
public String call() throws Exception {
try{
System.out.println(super.getClass().getName()+" 开始时间: "+System.currentTimeMillis());
for (int i = 0; i < 123456 ; i++) {
Math.random();
Math.random();
Math.random();
System.out.println("FCallable i:"+(i+1));
if(Thread.currentThread().isInterrupted() == true){
System.out.println(super.getClass().getName()+"中断了......");
throw new NullPointerException();
}
}
System.out.println(super.getClass().getName()+" 结束时间: "+System.currentTimeMillis());
}catch(Exception e){
e.printStackTrace();
System.out.println("通过显式try-catch捕获到异常,异常原因:"+e.getMessage());
throw e;
}
return super.getClass().getName();
}
}
运行类执行代码如下:
public class InvokeAnyRun {
public static void main(String[] args) {
try {
List list = new ArrayList();
list.add(new FCallable());
ExecutorService executorService = Executors.newCachedThreadPool();
String result = (String) executorService.invokeAny(list,1, TimeUnit.SECONDS);
System.out.println("已完成任务的返回值:"+result);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("进入捕获到 InterruptedException");
} catch (ExecutionException e) {
e.printStackTrace();
System.out.println("进入捕获到 ExecutionException");
} catch (TimeoutException e) {
e.printStackTrace();
System.out.println("进入捕获到 TimeoutException");
}
}
}
运行结果如下:
FCallable i:1
FCallable i:2
FCallable i:3
......
FCallable i:35480
FCallable i:35481
FCallable i:35482
进入捕获到 TimeoutException
com.ozx.concurrentprogram.executor.service.FCallable中断了......
通过显式try-catch捕获到异常,异常原因:null
java.util.concurrent.TimeoutException at java.util.concurrent.AbstractExecutorService.doInvokeAny(AbstractExecutorService.java:184) at java.util.concurrent.AbstractExecutorService.invokeAny(AbstractExecutorService.java:225) at com.ozx.concurrentprogram.executor.controller.InvokeAnyRun.main(InvokeAnyRun.java:27) java.lang.NullPointerException at com.ozx.concurrentprogram.executor.service.FCallable.call(FCallable.java:23) at com.ozx.concurrentprogram.executor.service.FCallable.call(FCallable.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)
从运行结果看出同时存在java.util.concurrent.TimeoutException超时异常和java.lang.NullPointerException空指针异常时,其中超时异常是在main线程中捕获到的,而空指针异常是在Callable中捕获到的。