您的位置:首页 > 编程语言 > Java开发

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐