博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
并发编程:执行器:3、运行N个任务并处理第一个返回结果(invokeAny() )
阅读量:2346 次
发布时间:2019-05-10

本文共 5392 字,大约阅读时间需要 17 分钟。

目录


threadPoolExecutor.invokeAny

当运行N个并发任务来解决同一个问题时,你只希望获取最早返回的结果,那么可以使用invokeAny方法。

案例功能

模拟用户验证,一个通过接口方式验证,另一个使用数据库方式验证。只要其中一种方式验证通过即返回结果。

一、主程序

package xyz.jangle.thread.test.n4_4.invokeany;import java.util.ArrayList;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * 	4.4、运行N个任务并处理第一个(最先的且正常的)返回结果 * 	案例:模拟用户验证,一个通过接口方式验证,另一个使用数据库方式验证。 * 	只要其中一种方式验证通过即返回结果。 * @author jangle * @email jangle@jangle.xyz * @time 2020年8月19日 下午5:38:03 *  */public class M {	public static void main(String[] args) {		var user = "user";		var password = "password";		var iValidator = new UserValidator("接口验证");		var dbValidator = new UserValidator("数据库验证");		var iTask = new ValidatorTask(iValidator, user, password);		var dbTask = new ValidatorTask(dbValidator, user, password);		ArrayList
taskList = new ArrayList
(); taskList.add(iTask); taskList.add(dbTask); ExecutorService threadPool = Executors.newCachedThreadPool(); String result; try { result = threadPool.invokeAny(taskList); System.out.println("Main:result:使用了"+result); } catch (InterruptedException e) { System.out.println("Main:中断异常"); e.printStackTrace(); }catch (ExecutionException e) { // 用户验证失败,两种方式都未正确返回。 System.out.println("Main:用户验证失败"); e.printStackTrace(); } threadPool.shutdown(); System.out.println("Main:执行结束"); }}

二、用户校验类

package xyz.jangle.thread.test.n4_4.invokeany;import java.util.Random;import java.util.concurrent.TimeUnit;/** * 	用户校验类 * @author jangle * @email jangle@jangle.xyz * @time 2020年8月19日 下午5:39:08 *  */public class UserValidator {	private final String name;	public UserValidator(String name) {		super();		this.name = name;	}	public boolean validate(String name, String password) {		var r = new Random();		long duration = (long) (Math.random() * 10);		System.out.println(this.name + "验证使用时间:" + duration);		try {			// 模拟验证时长			TimeUnit.SECONDS.sleep(duration);		} catch (InterruptedException e) {			e.printStackTrace();			return false;		}		// 采用随机方式模拟用户验证,即1/2的概率验证通过。		return r.nextBoolean();	}	public String getName() {		return name;	}	}

三、执行验证的任务线程类

package xyz.jangle.thread.test.n4_4.invokeany;import java.util.concurrent.Callable;/** * 执行验证的任务线程 *  * @author jangle * @email jangle@jangle.xyz * @time 2020年8月19日 下午5:44:10 *  */public class ValidatorTask implements Callable
{ private final UserValidator validator; private final String user; private final String password; public ValidatorTask(UserValidator validator, String user, String password) { super(); this.validator = validator; this.user = user; this.password = password; } @Override public String call() throws Exception { if (!validator.validate(user, password)) { System.out.println(validator.getName() + ":用户验证不通过"); throw new Exception("用户验证失败"); } System.out.println(validator.getName() + ":用户验证通过"); // 返回用户验证的方式 return validator.getName(); }}

四、执行结果

4.1、接口验证不通过,数据库验证通过。返回数据库验证结果。(使用了第二个正确的结果)

数据库验证验证使用时间:9接口验证验证使用时间:1接口验证:用户验证不通过数据库验证:用户验证通过Main:result:使用了数据库验证Main:执行结束

4.2、接口验证通过,返回接口验证结果(然后中断数据库验证的线程。使用了第一个正确的接口,中断第二个任务的执行)。

接口验证验证使用时间:0数据库验证验证使用时间:3接口验证:用户验证通过Main:result:使用了接口验证Main:执行结束java.lang.InterruptedException: sleep interrupted	at java.base/java.lang.Thread.sleep(Native Method)	at java.base/java.lang.Thread.sleep(Thread.java:339)	at java.base/java.util.concurrent.TimeUnit.sleep(TimeUnit.java:446)	at xyz.jangle.thread.test.n4_4.invokeany.UserValidator.validate(UserValidator.java:28)	at xyz.jangle.thread.test.n4_4.invokeany.ValidatorTask.call(ValidatorTask.java:28)	at xyz.jangle.thread.test.n4_4.invokeany.ValidatorTask.call(ValidatorTask.java:1)	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)	at java.base/java.lang.Thread.run(Thread.java:834)数据库验证:用户验证不通过

4.3、都不通过(抛出ExecutionException异常)

数据库验证验证使用时间:4接口验证验证使用时间:3接口验证:用户验证不通过数据库验证:用户验证不通过Main:用户验证失败java.util.concurrent.ExecutionException: java.lang.Exception: 用户验证失败	at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)	at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)	at java.base/java.util.concurrent.AbstractExecutorService.doInvokeAny(AbstractExecutorService.java:199)	at java.base/java.util.concurrent.AbstractExecutorService.invokeAny(AbstractExecutorService.java:220)	at xyz.jangle.thread.test.n4_4.invokeany.M.main(M.java:32)Caused by: java.lang.Exception: 用户验证失败	at xyz.jangle.thread.test.n4_4.invokeany.ValidatorTask.call(ValidatorTask.java:30)	at xyz.jangle.thread.test.n4_4.invokeany.ValidatorTask.call(ValidatorTask.java:1)	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)	at java.base/java.lang.Thread.run(Thread.java:834)Main:执行结束

 

转载地址:http://bbsvb.baihongyu.com/

你可能感兴趣的文章
福昕阅读器foxit reader Linux版
查看>>
Ubuntu 安装百度云客户端
查看>>
每天一个linux命令:locate
查看>>
Linux 环境下载百度云资源,Firefox插件(百度网盘助手)
查看>>
ubuntu Firefox/chrome adobe flash 插件安装
查看>>
OpenCV图像变换(仿射变换与透视变换)
查看>>
仿射变换与透视变换
查看>>
Ubuntu 16.04 上安装 CUDA 9.0 详细教程
查看>>
Verify You Have a CUDA-Capable GPU
查看>>
ROS中OpenCV的使用——人脸检测
查看>>
ROS学习笔记(1):在ROS中使用OpenCV进行简单的图象处理--原理篇
查看>>
ROS学习笔记(2):在ROS中使用OpenCV进行简单的图像处理---代码实现篇
查看>>
C语言中声明和定义详解
查看>>
ros代码中添加使用opencv库,cv::Mat和ros image之间的相互转换
查看>>
ROS 不能再详细的安装教程
查看>>
在ros底下安装opencv
查看>>
PHP页面纯静态化与伪静态化
查看>>
分享网页到微信朋友圈,显示缩略图的方法
查看>>
PHP参数类型限制
查看>>
IOS博客项目搭建-12-刷新数据-显示最新的微博数提示
查看>>