Android之多线程解析(二)之Runnable、Callable、FutureTask
来源:互联网 发布:兄弟连nginx视频教程 编辑:程序博客网 时间:2024/06/07 01:37
与多线程相关的方法—Callable,Future以及FutureTask
除了上文中一直分析的Runnable之外,Java中还存在Callbale,Future,FutureTask与多线程相关的概念,与Runnable不同的则是这三个方法只能用于线程池中,Runnable则可以同时在运用在Thread和线程池中。
Callable与Runnable功能相似,不同在与Callable是一个泛型接口,他有一个泛型参数V,该接口中有一个返回值(类型为V)的call()函数,而Runnable的run函数不能将结果返回到客户程序中:
public interface Callable<V>{ //返回V类型的结果 V call() throws Exception;}//为加深理解,假如Runnable的源码作为对比public interface Runnable{ //返回V类型的结果 public abstract void run();}
博客看到此处,即对Runnable以及Callable有了比较大致的了解,但是这两种机制存在着一个无法避免的缺陷,即一旦使用后就很难做到有效的控制。而Future的出现即解决了这种问题,Future为线程池制订了可管理的任务标准。Future提供了对Runnable或者Callable的任务的执行结果进行管理(取消,查询是否完成,获取结果,设置结果;分别对应着cancel,isDone,get,set函数,且get函数调用后会发生阻塞,直到执行完成返回结果)。Future声明如下:
public interface Future<V>{ boolean cancel(boolean mayInterruptIfRunning); boolean isCancelled(); boolean isDone(); V get() throws InterruptedException,ExecutionException; V get(long timeout,TimeUint unit) throws InterruptedException,ExecutionException,TimeoutException;}
Future只是定义了一些规范的接口,FutureTask则是具体的实现类。FutureTask实现了RunnableFuture,而RunnableFuture实现了Runnable又实现了Future这两个接口,因此FutureTask同时具有两者的能力。FutureTask代码如下:
public class FutureTask<V> implements RunnableFuture<V>{ //代码省略}
再看RunnabelFuture类定义:
public class RunnabelFuture<V> implements Runnable,Future<V>{ void run();}
FutureTask会像Thread包装Runnable那样对Runnable和Callbale进行包装,Runnbale与Callbale由构造函数注入。
public FutureTask(Callable<V> callable){ if(callable==null) throws new NullPointerException(); this.callable=callable; this.state=NEW; // ensure visibility of callable}public FutureTask(Runnable runnable,V result){ this.callable=Executors.callable(runnable,result); this.state=NEW; // ensure visibility of callable}
由上述代码即可看出,无论在构造函数中传输runnable或callable对象,都会被转换为callable对象,即可知道最终都是对Callable对象进行操作,该适配函数的实现如下:
public static <T> Callable<T> callable(Runnable task,T result){ if(task==null) throws new NullPointerException(); return new RunnableAdapter<T>(task,result);}static final class RunnableAdapter<T> implements Callable<T>{ final Runnable task; final T result; RunnableAdapter(Runnable task,T result){ this.task=task; this.result=result; } public T call(){ task.run(); return result; }}
由于FutureTask实现了Runnable,因此它既可以通过Thread包装来直接执行,也可提交给ExecuteService来执行。且可直接通过get()获取执行结果,该函数会一直阻塞到结果返回。因此,FutureTask既是Future,Runnable,又包装了Callable,即为两者的合体
下面通过一个Java程序简单演示Runnable,Callable,FutureTask的运用:
public class FutureDemo { static ExecutorService mExecutor=Executors.newSingleThreadExecutor(); public static void main(String[] args){ try { FutureWithRunnable(); FutureWithCallable(); FutureWithFutureTask(); } catch (Exception e) { // TODO: handle exception } } private static void FutureWithRunnable() throws InterruptedException,ExecutionException{ Future<?> result=mExecutor.submit(new Runnable() { public void run() { // TODO Auto-generated method stub fibc(20); } }); System.out.println("Future result from Runnable : "+result.get()); } private static void FutureWithCallable() throws InterruptedException,ExecutionException{ Future<Integer> result2=mExecutor.submit(new Callable<Integer>(){ public Integer call() throws Exception { // TODO Auto-generated method stub return fibc(20); } }); System.out.println("Future result from Callable : "+result2.get()); } private static void FutureWithFutureTask() throws InterruptedException,ExecutionException{ FutureTask<Integer> futuretask=new FutureTask<Integer>( new Callable<Integer>() { public Integer call() throws Exception { return fibc(20); } }); mExecutor.submit(futuretask); System.out.println("Future result from FutureTask : "+futuretask.get()); } private static int fibc(int num){ if(num == 0) return 0; if(num == 1) return 1; return fibc(num-1)+fibc(num-2); }}
运行结果为:
Future result from Runnable : null
Future result from Callable : 6765
Future result from FutureTask : 6765
由上述示例代码以及结果可以看出,以Runnable作为对象的执行后的结果无法通过get()函数方法获得。而使用Callable以及调用Callable的FutureTask可以通过get()函数获取执行后的结果。
- Android之多线程解析(二)之Runnable、Callable、FutureTask
- Java线程之Runnable,Callable,FutureTask
- Android(Java)之多线程结果返回——Future 、FutureTask、Callable、Runnable
- android Runnable Callable FutureTask
- Android之多线程解析(一)之Thread、Runnable
- 多线程之Runnable,Callable,Future,FutureTask
- Callable,Runnable,FutureTask
- Runnable、Callable、Future、FutureTask
- Runnable、Callable、Future、FutureTask
- android Callable Future FutureTask 解析
- Android线程池(九) Runnable、Callable、Executor、Future、FutureTask关系解读
- 线程结果回调Runnable、Callable、Future、FutureTask
- Android进阶——多线程系列之Thread、Runnable、Callable、Future、FutureTask
- Runnable、Callable、Executor、Future、FutureTask
- Runnable/Thread/Callable/Future/FutureTask
- Runnable、Callable、Future 和 FutureTask
- 线程 Callable FutureTask 入门
- Android并发二三事之Callable,Future,FutureTask
- VM无法启动Ubuntu
- CSS3 选择器
- 设计模式原则(3):依赖倒置原则
- Android常用工具之对字符串String进行MD5加密
- Python中关于decode、encode以及编码方式
- Android之多线程解析(二)之Runnable、Callable、FutureTask
- python之路——字符串操作
- LibSVM
- 禁用COOKIE后SESSION是如何传递
- 分治法排序
- [bzoj2555][后缀平衡树]SubString
- py thon 多线程(转一篇好文章)
- Codeforces Round #423 A. Restaurant Tables
- FutureTask源码浅析