java 并发 - 带返回结果的任务
2017-08-24 00:00
417 查看
一、概述
1、JDK5提供了有可返回值的任务的执行。java.util.concurrent 中 Callable 与 Futrue 用以实现带返回值的任务执行。2、 Callable:此接口有一个call()方法。在这个方法中,你必须实现任务的(处理)逻辑。Callable接口是一个参数化的接口。意味着你必须表明 call() 方法返回的数据类型。
Future:此接口有一些方法来保证 Callable 对象结果的获取和管理它的状态。
3、使用 Callable 与 Futrue 与使用 Runnable 最大的两个区别在于:
》Callable/Future是带返回值的;Runnable无法带返回值。
》Callable/Future所执行的任务是可取消的。Runnable的任务无法取消。
其关系如下所示:
二、详解
Callable接口1、Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。可返回值的任务必须实现 Callable 接口。
2、V call() throws Exception 方法用于计算结果,如果无法计算结果,则抛出一个异常。V是call方法的结果类型。
3、Callable接口定义了一个call方法可以作为线程的执行体,但 call 方法比 run 方法更强大:
call()方法可以有返回值。
call()方法可以申明抛出异常。
4、通过 ExecutorSevice 的submit()方法将Callable提交至线程池中执行,submit()方法返回一个Future实例。
5、使用 CompletionService 接口可以用于提交一组Callable任务,其take()方法返回已完成的一个Callable任务对应的Future实例。好比同时种了几块地的麦子,然后就等待收割。收割时,则是那块先成熟了,则先去收割哪块麦子。
Futrue接口
Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。如果为了可取消性而使用 Future 但又不提供可用的结果,则可以声明 Future<?> 形式类型、并返回 null 作为底层任务的结果。一旦计算完成,就不能再取消计算。
1、提交(submit()方法)Callable任务,可以获取一个Future实例。Futrue实例调用get()方法即可获取Callable任务返回值。
2、V get():返回Callable任务里的call()方法的返回值,调用该方法将导致线程阻塞,必须等到子线程结束才得到返回值。
三、案例-代码实现
import java.util.concurrent.Callable; public class FactorialCalculator implements Callable<Integer>{ private Integer number; public FactorialCalculator(Integer number) { this.number = number; } public Integer call() throws Exception { int result = 1; if(number != 0 && number != 1){ for(int i=1;i<=number;i++){ result *= i; Thread.sleep(500); } } return result; } }
import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ThreadPoolExecutor; public class FactorialCalculatorTest { public static void main(String[] args) { ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2); List<Future<Integer>> resultList = new ArrayList<Future<Integer>>(); for(int i=0;i<3;i++){ int random = new Random().nextInt(5); FactorialCalculator calculator = new FactorialCalculator(random); //调用执行者的submit()方法来提交FactorialCalculator任务给执行者。 //这个方法返回Future<Integer>对象来管理任务,并且最终获取它的结果。 Future<Integer> future = executor.submit(calculator); resultList.add(future); } do { System.out.println("Main:已完成的任务数量:" + executor.getCompletedTaskCount()); for (int i=0; i<resultList.size(); i++) { Future<Integer> result = resultList.get(i); System.out.println("Main: 任务staus:"+ result.isDone()+",i=" +i); // 遍历,输入 result 任务是否已完成. } try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } while (executor.getCompletedTaskCount() < resultList.size()); //如果执行者中的已完成任务数小于10,重复这个循环。 System.out.println("Main: Results:"); for (int i=0; i<resultList.size(); i++) { Future<Integer> result = resultList.get(i); Integer num = null; try { num = result.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } System.out.println("Main: 任务 结果:"+ num+",i=" +i); // 遍历,输入 result 结果 } executor.shutdown(); } }
//console结果: Main:已完成的任务数量:0 Main: 任务staus:false,i=0 Main: 任务staus:false,i=1 Main: 任务staus:false,i=2 Main:已完成的任务数量:0 Main: 任务staus:false,i=0 Main: 任务staus:false,i=1 Main: 任务staus:false,i=2 Main:已完成的任务数量:0 Main: 任务staus:false,i=0 Main: 任务staus:false,i=1 Main: 任务staus:false,i=2 Main:已完成的任务数量:1 Main: 任务staus:true,i=0 Main: 任务staus:false,i=1 Main: 任务staus:false,i=2 Main:已完成的任务数量:2 Main: 任务staus:true,i=0 Main: 任务staus:true,i=1 Main: 任务staus:false,i=2 Main:已完成的任务数量:2 Main: 任务staus:true,i=0 Main: 任务staus:true,i=1 Main: 任务staus:false,i=2 Main:已完成的任务数量:2 Main: 任务staus:true,i=0 Main: 任务staus:true,i=1 Main: 任务staus:false,i=2 Main: Results: Main: 任务 结果:6,i=0 Main: 任务 结果:24,i=1 Main: 任务 结果:24,i=2
相关文章推荐
- Java并发专题 带返回结果的批量任务执行
- Java并发专题 带返回结果的批量任务执行
- Java并发专题 带返回结果的批量任务运行 CompletionService ExecutorService.invokeAll
- Java并发专题 带返回结果的批量任务执行 CompletionService ExecutorService.invokeAll
- Java并发专题 带返回结果的批量任务执行 CompletionService ExecutorService.invokeAll
- Java并发专题 带返回结果的批量任务执行 CompletionService ExecutorService.invokeAll
- Java并发专题 带返回结果的批量任务执行 CompletionService ExecutorService.invokeAll
- Java并发专题 带返回结果的批量任务执行 CompletionService ExecutorService.invokeAll(转)
- Java并发专题 带返回结果的批量任务执行 CompletionService ExecutorService.invokeAll
- Java并发专题 带返回结果的批量任务执行
- Java并发专题 带返回结果的批量任务执行 CompletionService ExecutorService.invokeAll
- Java并发专题 带返回结果的批量任务执行 CompletionService ExecutorService.invokeAll
- Java并发编程高级篇(三):执行器中执行任务并返回结果
- Java并发专题 带返回结果的批量任务执行
- Java并发(6)带返回结果的任务执行
- Java并发专题 带返回结果的批量任务执行 CompletionService
- java并发带返回结果的批量任务执行
- 【Java并发】- 使用CompletionService异步收集任务结果
- 获取Executor提交的并发执行的任务返回结果的两种方式/ExecutorCompletionService使用
- Java线程总结(十三):并发包------线程返回结果Callable和 Future