java 并发 - 运行多个任务并执行第一个结果
2017-08-24 00:00
477 查看
一、概述
在并发编程中的一个常见的问题就是:当有多种并发任务解决一个问题时,你只对这些任务的第一个结果感兴趣。比如,你想要排序一个数组,你有多种排序算法, 你可以全部启用它们,但是只是获取第一个结果(对于给定数组排序最快的算法的结果)。说明:
1、使用 ThreadPoolExecutor.invokeAny(list); 让线程池来帮我们拿到最快返回结果的结果。//执行给定的任务,如果某个任务已成功完成(也就是未抛出异常),则返回其结果。一旦正常或异常返回后,则取消尚未完成的任务。
2、任务结束(完成)的标识是:未抛出异常,正常返回;
3、拿到第一个结果后,执行器会取消未完成的任务,而在多线程中:当线程在活动之前或活动期间处于正在等待、休眠或占用状态且该线程被中断时,抛出InterruptedException异常。
4、如果所有任务都抛出了异常,那么最终返回结果的时候也会抛出异常。(抛出的异常按照最后返回task)
5、invokeAll()方法:当所有任务完成时返回所有任务的future列表。
二、实现
import java.util.Random; /** * 用户验证 */ public class UserValidator{ private String name; public UserValidator(String name){ this.name = name; } public boolean validator(String name){ Random random = new Random(); try { Thread.sleep(1000*random.nextInt(2)); System.out.println(Thread.currentThread().getName() + "-验证:休眠一下-name:" + this.name); } catch (InterruptedException e) { //e.printStackTrace(); System.out.println(Thread.currentThread().getName() + "-取消==该任务被中断"); return false; } return random.nextBoolean(); } public String getName() { return name; } }
import java.util.concurrent.Callable; public class TaskValidator implements Callable<String>{ private UserValidator userValidator; private String user; public TaskValidator(UserValidator userValidator, String user) { this.userValidator = userValidator; this.user = user; } @Override public String call() throws Exception { if(!userValidator.validator(user)){ System.out.println(Thread.currentThread().getName()+ "-验证操作:The user has not been-name:"+userValidator.getName()); throw new Exception(Thread.currentThread().getName()+"-Error validating user-name:"+userValidator.getName()); } System.out.println(Thread.currentThread().getName()+"-验证操作:The user has been found-name:"+userValidator.getName()); return userValidator.getName(); } }
import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; public class MainValidatorTest { public static void main(String[] args) { String user = "test"; UserValidator userValidator = new UserValidator("loap"); UserValidator userValidator2 = new UserValidator("database"); TaskValidator taskValidator = new TaskValidator(userValidator, user); TaskValidator taskValidator2 = new TaskValidator(userValidator2, user); List<TaskValidator> list = new ArrayList<TaskValidator>(); list.add(taskValidator); list.add(taskValidator2); ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool(); String result; try { //接收任务数列,并启动它们,返回完成时没有抛出异常的第一个 任务的结果。该方法返回的数据类型与启动任务的call()方法返回的类型一样。 result = executor.invokeAny(list); System.out.println("Main: Result -- 最后结果: " + result); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } executor.shutdown(); System.out.println("Main: End of the Execution"); } }
//console结果: pool-1-thread-1-验证:休眠一下-name:loap pool-1-thread-1-验证操作:The user has been found-name:loap Main: Result -- 最后结果: loap pool-1-thread-2-取消==该任务被中断 pool-1-thread-2-验证操作:The user has not been-name:database Main: End of the Execution
相关文章推荐
- Java并发编程高级篇(四):运行多个任务并处理第一个结果
- Java并发专题 带返回结果的批量任务执行
- Java并发专题 带返回结果的批量任务执行 CompletionService ExecutorService.invokeAll
- Java并发编程高级篇(五):运行多个任务并处理所有结果
- java并发带返回结果的批量任务执行
- Java并发(6)带返回结果的任务执行
- Java并发编程高级篇(三):执行器中执行任务并返回结果
- Java并发专题 带返回结果的批量任务执行
- Java并发专题 带返回结果的批量任务执行 CompletionService ExecutorService.invokeAll
- Java并发专题 带返回结果的批量任务执行 CompletionService
- java 如何运行多个任务并处理返回第一个结果
- Java并发专题 带返回结果的批量任务执行 CompletionService ExecutorService.invokeAll
- Java并发专题 带返回结果的批量任务执行 CompletionService ExecutorService.invokeAll
- Java并发专题 带返回结果的批量任务运行 CompletionService ExecutorService.invokeAll
- 并发编程--运行多个任务并处理第一个结果
- Java并发专题 带返回结果的批量任务执行
- Java并发专题 带返回结果的批量任务执行 CompletionService ExecutorService.invokeAll(转)
- Java并发专题 带返回结果的批量任务执行 CompletionService ExecutorService.invokeAll
- Java并发专题 带返回结果的批量任务执行 CompletionService ExecutorService.invokeAll
- Java并发专题 带返回结果的批量任务执行