Java并发编程:Callable和Future使用
2016-04-06 13:32
555 查看
在Java中,创建线程一般有两种方式,一种是继承Thread类,一种是实现Runnable接口。然而,这两种方式的缺点是在线程任务执行结束后,无法获取执行结果。我们一般只能采用共享变量或共享存储区以及线程通信的方式实现获得任务结果的目的。
不过,Java中,也提供了使用Callable和Future来实现获取任务结果的操作。Callable用来执行任务,产生结果,而Future用来获得结果。
Callable接口与Runnable接口是否相似,查看源码,可知Callable接口的定义如下:
可以看到,与Runnable接口不同之处在于,call方法带有泛型返回值V。
我们通过简单的例子来体会使用Callable和Future来获取任务结果的用法。
假设我们现在有一个任务,要计算出1-10000之间的所有数字的和,为了提升计算速度,我们使用两个线程,第一个线程计算1-5000的和,另外有一个线程计算5001-10000之间的数字的和。为了更好的展示效果,让每个线程在计算过程中休眠5s。
不过,Java中,也提供了使用Callable和Future来实现获取任务结果的操作。Callable用来执行任务,产生结果,而Future用来获得结果。
Callable接口与Runnable接口是否相似,查看源码,可知Callable接口的定义如下:
@FunctionalInterface public interface Callable<V> { /** * Computes a result, or throws an exception if unable to do so. * * @return computed result * @throws Exception if unable to compute a result */ V call() throws Exception; }
可以看到,与Runnable接口不同之处在于,call方法带有泛型返回值V。
我们通过简单的例子来体会使用Callable和Future来获取任务结果的用法。
假设我们现在有一个任务,要计算出1-10000之间的所有数字的和,为了提升计算速度,我们使用两个线程,第一个线程计算1-5000的和,另外有一个线程计算5001-10000之间的数字的和。为了更好的展示效果,让每个线程在计算过程中休眠5s。
import java.util.ArrayList; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class TestMain{ public static void main(String[] args) throws InterruptedException, ExecutionException { ExecutorService executor = Executors.newCachedThreadPool(); ArrayList<Future<Integer>> resultList = new ArrayList<>(); //创建并提交任务1 AddNumberTask task1 = new AddNumberTask(1, 5000); Future<Integer> future1 = executor.submit(task1); resultList.add(future1); //创建并提交任务2 AddNumberTask task2 = new AddNumberTask(5001, 10000); Future<Integer> future2 = executor.submit(task2); resultList.add(future2); executor.shutdown(); int total = 0; for(Future<Integer> future : resultList){ while(true){ if(future.isDone() && !future.isCancelled()){ int sum = future.get(); total += sum; break; } else{ Thread.sleep(100); } } } System.out.println("total sum is " + total); } } class AddNumberTask implements Callable<Integer>{ private int start; private int end; public AddNumberTask(int start, int end) { // TODO Auto-generated constructor stub this.start = start; this.end = end; } @Override public Integer call() throws Exception { // TODO Auto-generated method stub int totalSum = 0; for(int i = start; i <= end; i++){ totalSum += i; } Thread.sleep(5000); return totalSum; } }
相关文章推荐
- Maven Integration for Eclipse 正确地址
- java实现多线程
- Java 标准日志工具 Log4j 的使用(附源代码)
- Java基础-数组的基本操作(2)
- 用xutils3.0来访问 spring boot,带权限验证
- C# Java间进行RSA加密解密交互(三)
- C# Java间进行RSA加密解密交互(二)
- C# Java间进行RSA加密解密交互
- Java中Iterator(迭代器)的用法及其背后机制的探究
- Java内部类的一些总结
- java集合框架随写1
- java资源大全
- Java 将字节数组转化为16进制的多种方案
- Java环境变量的作用以及如何配置环境变量
- Java多线程之实现方式
- java创建和销毁对象
- LeetCode(java)1. Two Sum
- java向上取整向下取整
- java向上取整向下取整
- 初识Java