java.util.concurrent包(4)——Callable和Future

简介:
Callable和Future,一个产生结果,一个拿到结果。

Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结果,并且无法抛出返回结果的异常,而Callable功能更强大一些,被线程执行后,可以返回值,这个返回值可以被Future拿到,也就是说,Future可以拿到异步执行任务的返回值,下面来看一个简单的例子:

public class CallableAndFuture
{
public static void main(String[] args)
{
Callable<Integer> callable = new Callable<Integer>()
{
public Integer call() throws Exception
{
return new Random().nextInt(100);
}
};
FutureTask<Integer> future = new FutureTask<Integer>(callable);
new Thread(future).start();
try
{
// 做其他的事情
Thread.sleep(5000);
System.out.println(future.get());
}
catch (InterruptedException e)
{
e.printStackTrace();
}
catch (ExecutionException e)
{
e.printStackTrace();
}
}
}

FutureTask实现了两个接口,Runnable和Future,所以既可以作为Runnable被线程执行,又可作为Future得到Callable的返回值,这个组合的使用有什么好处呢?假设有一个很耗时的返回值需要计算,并且这个返回值不是立刻需要的话,就可以使用这个组合,用另一个线程去计算返回值,而当前线程在使用这个返回值之前可以做其它的操作,等到需要这个返回值时,再通过Future得到,岂不美哉!这里有一个Future模式的介绍:http://openhome.cc/Gossip/DesignPattern/FuturePattern.htm。

下面来看另一种方式使用Callable和Future,通过ExecutorService的submit方法执行Callable,并返回Future。

public class CallableAndFuture2
{
public static void main(String[] args)
{
ExecutorService threadpool = Executors.newFixedThreadPool(1);
Future<String> future = threadpool.submit(new Callable<String>()
{
public String call() throws Exception
{
return "XY";
}
});

try
{
// 做其他的事情
Thread.sleep(5000);
System.out.println(future.get());
}
catch (InterruptedException e)
{
e.printStackTrace();
}
catch (ExecutionException e)
{
e.printStackTrace();
}
}
}
代码是不是简化了很多,ExecutorService继承自Executor,它的目的是为管理Thread对象,从而简化并发编程,Executor使我们无需显示的去管理线程的生命周期,是JDK 5之后启动任务的首选方式。

执行多个带返回值的任务,并取得多个返回值,代码如下:
public class CallableAndFuture3
{
public static void main(String[] args)
{
ExecutorService threadPool = Executors.newCachedThreadPool();
CompletionService<Integer> cs = new ExecutorCompletionService<Integer>(threadPool);
for (int i = 1; i <= 10; i++)
{
final int taskID = i;
cs.submit(new Callable<Integer>()
{
public Integer call() throws Exception
{
return taskID;
}
});
}
// 做其他的事情
for (int i = 1; i <= 10; i++)
{
try
{
System.out.println(cs.take().get());
}
catch (InterruptedException e)
{
e.printStackTrace();
}
catch (ExecutionException e)
{
e.printStackTrace();
}
}
}
}

原帖地址:http://blog.csdn.net/ghsau/article/details/7451464
目录
相关文章
|
29天前
|
Java 数据安全/隐私保护
JAVA包
JAVA包
12 0
|
3月前
|
Java
JAVA JUC Callable 接口
【1月更文挑战第5天】JAVA JUC Callable 接口
|
4月前
|
存储 Java 编译器
Java编程中,包声明(Package Declaration)
Java编程中,包声明(Package Declaration)
68 1
|
4月前
|
Java 关系型数据库 Linux
Linux|Java|jar包的解压和重新打包(更新配置)
Linux|Java|jar包的解压和重新打包(更新配置)
64 0
|
4天前
|
Java Maven
【Java报错】显示错误“Error:java: 程序包org.springframework.boot不存在“
【Java报错】显示错误“Error:java: 程序包org.springframework.boot不存在“
23 3
|
3月前
|
分布式计算 Java 大数据
IO流【Java对象的序列化和反序列化、File类在IO中的作用、装饰器模式构建IO流体系、Apache commons-io工具包的使用】(四)-全面详解(学习总结---从入门到深化)
IO流【Java对象的序列化和反序列化、File类在IO中的作用、装饰器模式构建IO流体系、Apache commons-io工具包的使用】(四)-全面详解(学习总结---从入门到深化)
51 0
|
22天前
|
Java 数据库连接 API
Java 学习路线:基础知识、数据类型、条件语句、函数、循环、异常处理、数据结构、面向对象编程、包、文件和 API
Java 是一种广泛使用的、面向对象的编程语言,始于1995年,以其跨平台性、安全性和可靠性著称,应用于从移动设备到数据中心的各种场景。基础概念包括变量(如局部、实例和静态变量)、数据类型(原始和非原始)、条件语句(if、else、switch等)、函数、循环、异常处理、数据结构(如数组、链表)和面向对象编程(类、接口、继承等)。深入学习还包括包、内存管理、集合框架、序列化、网络套接字、泛型、流、JVM、垃圾回收和线程。构建工具如Gradle、Maven和Ant简化了开发流程,Web框架如Spring和Spring Boot支持Web应用开发。ORM工具如JPA、Hibernate处理对象与数
88 3
|
26天前
|
Java
Java包及访问限定
Java包及访问限定
8 0
|
30天前
|
Java
Java并发编程:理解并使用Future和Callable接口
【2月更文挑战第25天】 在Java中,多线程编程是一个重要的概念,它允许我们同时执行多个任务。然而,有时候我们需要等待一个或多个线程完成,然后才能继续执行其他任务。这就需要使用到Future和Callable接口。本文将深入探讨这两个接口的用法,以及它们如何帮助我们更好地管理多线程。
|
1月前
|
Java 数据安全/隐私保护
Java的包机制
Java的包机制
25 8
Java的包机制