java 并发 - 运行多个任务并执行第一个结果

一、概述

在并发编程中的一个常见的问题就是:当有多种并发任务解决一个问题时,你只对这些任务的第一个结果感兴趣。比如,你想要排序一个数组,你有多种排序算法, 你可以全部启用它们,但是只是获取第一个结果(对于给定数组排序最快的算法的结果)。

说明:

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

 

转载于:https://my.oschina.net/u/1387400/blog/1522735

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值