java并发编程第四章 线程执行器(2)
来源:互联网 发布:数据文员主要做什么的 编辑:程序博客网 时间:2024/05/29 03:49
4.运行多个任务并处理第一个结果
并发编程中的常见问题就是,当采用多个并发任务解决一个问题时,往往只关心这些任务的第一个结果。这里我们使用ThreadPoolExecutor类实现该场景。
范例允许用户通过两种验证机制进行验证,但是只要有一种机制验证成功,那么这个用户就验证通过了。
关键在于ThreadPoolExecutor类的方法invokeAny()方法接收到一个任务列表,然后运行任务,返回第一个完成任务且没有抛出异常的任务执行结果。
这个方法返回的类型与任务里的call()
方法返回的类型相同,在这个范例中,将返回String类型的值。
这里有两个任务可以番红花true值,或者抛出Exception异常。因此有下面四种情况
1.如果两个任务都返回true值,那么InvokeAny()方法的结果就是首次完成任务的名称。
2.如果第一个任务返回true值,第二个任务抛出Exception异常,那么invokeAny方法的结果就是第一个任务的名称。
3.如果第一个任务抛出Exception异常,第二个任务返回true值,那么InvokeAny()方法的结果就是第二个任务的名称。
4.如果两个任务都抛出异常Exception,那么InvokeAny()方法将抛出ExecutionException异常。
该方法还有一个其他版本
invokeAny(Collection<? extends Callable<T>> tasks, long timeout,TimeUnit timeUnit),这个方法执行所有的任务,如果在给定的时间内某个任务已经完成,则返回其结果。
3.Main 测试类
5.运行多个任务并处理所有结果
如果想要等待任务的结束,可以使用下面的方法:
1.如果任务执行结束,那么Future接口的isDone()方法将返回true。
2.在调用shutdown()方法后,ThreadPoolExecutor类的awaitTermination()方法会将线程休眠,直到所有的任务都执行完毕。
这两个方法有一些缺点
1.方法一中仅仅可以控制任务的完成与否。
2.方法二中必须关闭执行器来等待一个线程,否则调用这个方法的线程将立即返回。
ThreadPoolExecutor类还提供了一个方法,允许发送一个任务列表给执行器,并等待列表中所有任务执行完成。该方法就是InvokeAll(),返回一个List的Future对象。
关于InvokeAll()方法的重要地方,就是使用Future对象仅用来获取任务的结果。
当所有的任务执行结束时这个方法也执行结束了,如果在返回的Future对象上调用isDone()方法,那么所有的调用将返回true值。
另一个版本的方法:
InvokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit timeUnit)当所有的任务都执行完毕,或者超时的时候(无论哪个首先发生),
这个方法将返回
保持任务状态和结果的Future列表。
3.Main测试类
并发编程中的常见问题就是,当采用多个并发任务解决一个问题时,往往只关心这些任务的第一个结果。这里我们使用ThreadPoolExecutor类实现该场景。
范例允许用户通过两种验证机制进行验证,但是只要有一种机制验证成功,那么这个用户就验证通过了。
关键在于ThreadPoolExecutor类的方法invokeAny()方法接收到一个任务列表,然后运行任务,返回第一个完成任务且没有抛出异常的任务执行结果。
这个方法返回的类型与任务里的call()
方法返回的类型相同,在这个范例中,将返回String类型的值。
这里有两个任务可以番红花true值,或者抛出Exception异常。因此有下面四种情况
1.如果两个任务都返回true值,那么InvokeAny()方法的结果就是首次完成任务的名称。
2.如果第一个任务返回true值,第二个任务抛出Exception异常,那么invokeAny方法的结果就是第一个任务的名称。
3.如果第一个任务抛出Exception异常,第二个任务返回true值,那么InvokeAny()方法的结果就是第二个任务的名称。
4.如果两个任务都抛出异常Exception,那么InvokeAny()方法将抛出ExecutionException异常。
该方法还有一个其他版本
invokeAny(Collection<? extends Callable<T>> tasks, long timeout,TimeUnit timeUnit),这个方法执行所有的任务,如果在给定的时间内某个任务已经完成,则返回其结果。
实例代码:
1、验证任务类
public class TaskValidator implements Callable<String>{private UserValidator validator;private String user;private String password;public TaskValidator(UserValidator validator, String user, String password) {this.validator = validator;this.user = user;this.password = password;}@Overridepublic String call() throws Exception {if(!validator.validate(user, password)){System.out.printf("%s: The user has not been found\n",validator.getName());throw new Exception("Erro validating user");}System.out.printf("%s The user has been fund\n",validator.getName());return validator.getName();}}
2.用户验证
/** * * @author fcs * @date 2015-5-5 * 描述:运行多个任务并处理第一个结果 * 说明: */public class UserValidator {private String name;public UserValidator(String name) {super();this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}public boolean validate(String name,String password){Random random = new Random();//模拟处理时间long duration = (long)(Math.random() *10);System.out.printf("Validator %s: validating a user during %d seconds\n",this.name,duration);try {TimeUnit.SECONDS.sleep(duration);} catch (InterruptedException e) {e.printStackTrace();}//返回随机的Boolean值,表示是否通过验证return random.nextBoolean();}}
3.Main 测试类
public class Main {public static void main(String[] args) {String user = "test";String password = "test";UserValidator user1 = new UserValidator("LDAP");UserValidator user2 = new UserValidator("DataBase");TaskValidator task1 = new TaskValidator(user1, user, password);TaskValidator task2 = new TaskValidator(user2, user, password);List<TaskValidator> task1List = new ArrayList<TaskValidator>();task1List.add(task1);task1List.add(task2);ExecutorService executor = (ExecutorService)Executors.newCachedThreadPool();String result;try{result = executor.invokeAny(task1List);System.out.printf("Main : Result: %s\n",result);}catch(Exception e){e.printStackTrace();}executor.shutdown(); //终止执行器System.out.println("Main : End of the execution");}}
5.运行多个任务并处理所有结果
如果想要等待任务的结束,可以使用下面的方法:
1.如果任务执行结束,那么Future接口的isDone()方法将返回true。
2.在调用shutdown()方法后,ThreadPoolExecutor类的awaitTermination()方法会将线程休眠,直到所有的任务都执行完毕。
这两个方法有一些缺点
1.方法一中仅仅可以控制任务的完成与否。
2.方法二中必须关闭执行器来等待一个线程,否则调用这个方法的线程将立即返回。
ThreadPoolExecutor类还提供了一个方法,允许发送一个任务列表给执行器,并等待列表中所有任务执行完成。该方法就是InvokeAll(),返回一个List的Future对象。
关于InvokeAll()方法的重要地方,就是使用Future对象仅用来获取任务的结果。
当所有的任务执行结束时这个方法也执行结束了,如果在返回的Future对象上调用isDone()方法,那么所有的调用将返回true值。
另一个版本的方法:
InvokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit timeUnit)当所有的任务都执行完毕,或者超时的时候(无论哪个首先发生),
这个方法将返回
保持任务状态和结果的Future列表。
实例代码:
1.存储实例中并发任务产生的结果
/** * * @author fcs * @date 2015-5-5 * 描述:运行多个任务并处理所有结果 * 说明: */public class Result {<span style="white-space:pre"></span>private String name;<span style="white-space:pre"></span>private int value;<span style="white-space:pre"></span>public String getName() {<span style="white-space:pre"></span>return name;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>public void setName(String name) {<span style="white-space:pre"></span>this.name = name;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>public int getValue() {<span style="white-space:pre"></span>return value;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>public void setValue(int value) {<span style="white-space:pre"></span>this.value = value;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}2.Task类
public class Task implements Callable<Result> {private String name;public Task(String name) {this.name = name;}@Overridepublic Result call() throws Exception {System.out.printf("%s: Starting\n",this.name);long duration = (long)(Math.random() * 10);System.out.printf("%s: waiting %d seconds for results\n",this.name,duration);TimeUnit.SECONDS.sleep(duration);int value = 0;for(int i =0 ;i< 5;i++){value+=(int)(Math.random() * 100);}Result result = new Result();result.setName(this.name);result.setValue(value);return result;}}
3.Main测试类
public class Main {public static void main(String[] args) {ExecutorService executor = (ExecutorService)Executors.newCachedThreadPool();List<Task> taskList = new ArrayList<Task>();for(int i =0 ;i < 3;i++){Task task = new Task(i+"");taskList.add(task);}List<Future<Result>> resultList = null;try {//该方法返回上一步创建的Future类型的列表resultList = executor.invokeAll(taskList);} catch (InterruptedException e) {e.printStackTrace();}executor.shutdown();System.out.println("Main: Printing the results");for(int i =0;i< resultList.size();i++){Future<Result> future = resultList.get(i);try {Result result = future.get();System.out.println(result.getName()+" : "+result.getValue());} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}}}}
0 0
- java并发编程第四章 线程执行器(2)
- java并发编程第四章 线程执行器(1)
- java并发编程第四章线程执行器(3)
- java并发编程第四章 线程执行器(4)
- java并发编程第四章 线程执行器(5)
- java并发编程之线程执行器
- Java7并发编程指南——第四章:线程执行器
- Java并发编程-16-线程执行器-Executor Framework
- Java并发编程类学习三(线程的执行)
- 第四章线程执行器
- 并发编程--创建线程执行器
- java并发编程第四章 总结
- Java并发编程(2)-线程
- java编程思想---第四章(控制执行流程)
- Java并发编程:线程的创建和执行
- Java并发编程示例(六):等待线程执行终止
- 《Java编程思想第四版》笔记---21章(2) 并发
- Java编程思想第四版-第四章(控制执行流程 )笔记
- NSString方法总结
- i2c_client,i2c_adapter和I2C-core的简介
- Android xml 文件代码自动提示
- 日经社説 20150614 世界経済の局面変化どう乗り切る
- 【LeetCode】Basic Calculator 解题报告
- java并发编程第四章 线程执行器(2)
- win7平台下vs2013配置opencv3.0
- NSAttributedString详解
- 社説 20150614 新銀行東京 経営統合でも残る独断のツケ
- 时空上下文视觉跟踪(STC)算法的解读与代码复现
- eclipse Ctrl +左键查看源代码提示找不到源
- 社説 20150614 廃炉工程表改訂 リスク低減で作業の進展図れ
- swift dataStruct
- UIApplication 生命周期