ExecutorService的invokeAny方法
一、此方法获得最先完成任务的结果,即Callable<T>接口中的call的返回值,在获得结果时,会中断其他正在执行的任务
示例代码:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; public class MyinvokeAny { public static void main(String[] args) {
// TODO 自动生成的方法存根
List<Callable<String>> list=new ArrayList<Callable<String>>();
list.add(new MyCallable_iAny1());
list.add(new MyCallable_iAny2());
ExecutorService executor=Executors.newCachedThreadPool(); try {
String str=executor.invokeAny(list);//取出第一个执行完的任务时,其他未完成的任务会被中断
System.out.println(str);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (ExecutionException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} } }
class MyCallable_iAny1 implements Callable<String>{ @Override
public String call() throws Exception {
// TODO 自动生成的方法存根
try{
for(int i=0;i<123456;i++){
for(int j=0;j<123;j++){
if(Thread.currentThread().isInterrupted()){
System.out.println("this is a exception");
throw new InterruptedException("A InterruptedException");
}
}
}
}catch(Exception e){
e.printStackTrace();
throw e;
} System.out.println("finish");
return "call_1";
} }
class MyCallable_iAny2 implements Callable<String>{ @Override
public String call() throws Exception {
// TODO 自动生成的方法存根
Thread.sleep(1000);
return "call_2";
} }
运行结果:
call_2java.lang.InterruptedException: A InterruptedException this is a exception
at myexecutorservice.MyCallable_iAny1.call(myinvokeAny.java:53)
at myexecutorservice.MyCallable_iAny1.call(myinvokeAny.java:1)
at java.util.concurrent.FutureTask.run(Unknown Source)
二、异常的处理
对于会先完成,但会出现异常的任务,ExecutorService会将关注点换到下一个任务,若果所有的任务都出现异常,那么将会只获得最后一个任务的异常(例如,有3个任务A,B,C,这三个任务都会出现异常,但是只会获得C任务的异常)
示例代码:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; public class myinvokeAny { public static void main(String[] args) {
// TODO 自动生成的方法存根
List<Callable<String>> list=new ArrayList<Callable<String>>();
list.add(new MyCallable_iAny1());
list.add(new MyCallable_iAny2());
ExecutorService executor=Executors.newCachedThreadPool(); try {
String str=executor.invokeAny(list);//取出第一个执行完的任务时,其他未完成的任务会被中断 System.out.println(str);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (ExecutionException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} } }
class MyCallable_iAny1 implements Callable<String>{ @Override
public String call() throws Exception {
// TODO 自动生成的方法存根
Thread.sleep(2000); System.out.println("finish");
return "call_1";
} }
class MyCallable_iAny2 implements Callable<String>{ @Override
public String call() throws Exception {
// TODO 自动生成的方法存根
Thread.sleep(1000);
if(true){
throw new Exception("myException_B");
}
return "call_2";
} }
运行结果:
finish
call_1
由此,我们可以看出,MyCallable_iAny2任务出现异常,从而将任务的关注点移到了MyCallable_iAny1任务,并不会打印出异常信息。如果,想打印出异常信息,需要这样写:
写法一:
try{
if(true){
throw new Exception("myException_B");
}
}catch(Exception e){
e.printStackTrace();
}
运行结果:
java.lang.Exception: myException_B
call_2
at myexecutorservice.MyCallable_iAny2.call(myinvokeAny.java:76)
at myexecutorservice.MyCallable_iAny2.call(myinvokeAny.java:1)
这里获得了异常任务的结果,这是因为MyCallable_iAny2的异常状态未上报,这导致线程池认为其是正确的,从而未将关注点换到下一个任务
写法二:
try{
if(true){
throw new Exception("myException_B");
}
}catch(Exception e){
// e.printStackTrace();
throw e;
}
运行结果:
finish
call_1
这里抛出了异常,从了线程池将关注点换到了下一个任务
ExecutorService的invokeAny方法的更多相关文章
- ExecutorService的invokeAny方法注意
package com.msxf.datasource.thirdpart.service.extface; import java.util.HashSet; import java.util.Li ...
- ExecutorService的submit方法使用
在Java5之后,并发线程这块发生了根本的变化,最重要的莫过于新的启动.调度.管理线程的一大堆API了.在Java5以后,通过Executor来启动线程比用Thread的start()更好.在新特征中 ...
- ExecutorService的submit方法的坑
先看一段代码: public Future<?> submit(Runnable task) { if (task == null) throw new NullPointerExcept ...
- ExecutorService
接口 java.util.concurrent.ExecutorService 表述了异步执行的机制,并且可以让任务在后台执行.壹個 ExecutorService 实例因此特别像壹個线程池.事实上, ...
- Java并发编程核心方法与框架-ExecutorService的使用
在ThreadPoolExecutor中使用ExecutorService中的方法 方法invokeAny()和invokeAll()具有阻塞特性 方法invokeAny()取得第一个完成任务的结果值 ...
- ExecutorService.invokeAny()和ExecutorService.invokeAll()的使用剖析
ExecutorService是JDK并发工具包提供的一个核心接口,相当于一个线程池,提供执行任务和管理生命周期的方法.ExecutorService接口中的大部分API都是比较容易上手使用的,本文主 ...
- [翻译][Java]ExecutorService的正确关闭方法
https://blog.csdn.net/zaozi/article/details/38854561 https://blog.csdn.net/z69183787/article/details ...
- 线程池 多线程运行结束后 如何关闭? ExecutorService的正确关闭方法
前言 最近在使用ExecutorService的时候,对于与ExecutorService相关的概念有些迷糊, 加上本身ExecutorService内部的有些方法名在取名上也容易让使用者误解,导致 ...
- ExecutorService的execute和submit方法
三个区别: 1.接收的参数不一样 2.submit有返回值,而execute没有 Method submit extends base method Executor.execute by creat ...
随机推荐
- rest-assured的默认值与Specification重用
一.默认值 rest-assured发起请求时,默认使用的host为localhost,端口为8080,如果你想使用不同的端口,你可以这样做: given().port(80)...... 或者是简单 ...
- abp架构添加实体并使用迁移功能生成表
参考: https://aspnetboilerplate.com/Pages/Articles/Introduction-With-AspNet-Core-And-Entity-Framework- ...
- 【算法笔记】B1037 在霍格沃茨找零钱
1037 在霍格沃茨找零钱 (20 分) 如果你是哈利·波特迷,你会知道魔法世界有它自己的货币系统 —— 就如海格告诉哈利的:“十七个银西可(Sickle)兑一个加隆(Galleon),二十九个纳特( ...
- vue脚手架初始化的项目 npm run build 无效,没有反应
找到build文件夹的check-versions文件,注释掉如图所以代码即可.
- Spring Boot 例一 实现jsonp接口
1.新建项目(选择quikstart) 2.增加spring boot 依赖 <dependency> <groupId>org.springframework.boot< ...
- PHP操作Access数据库
ADO是一项微软的技术,ADO指ActiveX数据对象(ActiveX Data Objects). 链接数据库 <?php header("Content-Type:text/htm ...
- 【记录】adb连不上手机
1.\用户\.android文件夹下新建adb_usb.ini,内容为手机的VID值,如0x9BB5 2.重启adb adb kill-server adb start-server adb devi ...
- 【总结】sqlmap-tamper编写小结
目的:修改sqlmap中的tamper脚本来绕过代码对特定参数的过滤和转义 环境:win10.phpstudy2016.sqli-labs-master平台 工具:sqlmap.burpsuite 地 ...
- Linux混杂设备驱动
1. Linux混杂设备驱动模型 ① 在Linux系统中,存在一类字符设备,它们拥有相同的主设备号(10),但次设备号不同,我们称这类设备为混杂设备(miscdevice).所有混杂设备形成一个链表, ...
- kindeditor<=4.1.5文件上传漏洞
最近发现很多网页篡改与暗链都是利用kindeditor编辑器,于是搜了一下kindeditor的漏洞,发现低于4.1.5版本的存在文件上传的漏洞,可以上传txt,html后缀的文档,许多恶意的文档貌似 ...