多线程--callable、Future、FutureTask
2016-12-18 13:19
239 查看
除了Runnable外,JAVA中还有callable、Future、FutureTask这几个线程。 与Runnable不同的是,他们只能运用到线程池中,而Runnable可以使用到Thread中。
一、Callable
他和Runnable功能大致相同,不同的是他有一个返回值。
他的声明如下:
public interface Callable<V> { //返回V类型的结果 V call() throws Exception{} }
二、Future
Runnable和Callable都无法对线程进行控制,一旦开始就无法进行管理。而Future可以执行cancel、isDone、get、set等方法。具体声明如下:
public interface Future<V> { //取消线程 boolean cancel(boolean mayInterruptIfRunning); //是否已经取消 boolean isCancelled; //是否已经完成 boolean isDone(); //获取结果,若未完成则阻塞直到任务完成 V get() throws InterruptedException,ExecutionException; //获取结果,若未完成则阻塞直到任务完成、或者超时。unit为时间单位 V get(long Timeout , TimeUnit unit) throws InterruptedException,ExecutionException,timeoutException; }
get方法会阻塞直到任务完成,返回结果
三、FutureTask
它是Future接口的实现类,同时还实现了Runnable接口。
public class FutureTask<V> implements RunnableFuture<V> { public FutureTask(Callable<V> callable) { if (callable == null) throw 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 } } public interface RunnableFuture<V> extends Runnable, Future<V> { void run(); }
可以看见FutureTask实现了 RunnableFuture,而 RunnableFuture继承了Runnable, Future;其中callable和Runnable通过构造函数注入,不过通过代码,我们可以知道注入的Runnable最后也转换为callable类型的任务。
由此可见,FutureTask实现了Runnable接口,可以通过Thread来直接运行,也可以提交到线程池,同时还能通get拿到结果。
现在通过一个DEMO来直观的展示他们之间的区别。
public class mFutureDemo { //线程池 static ExecutorService mExecutor = Executors.newSingleThreadExecutor(); //主程序 public static void main(){ } private static void runnable() throws ExecutionException, InterruptedException { Future<?> result = mExecutor.submit(new Runnable() { @Override public void run() { fibc(20); } }); System.out.print("runnable"+result.get()); } private static void callable() throws ExecutionException, InterruptedException { Future<Integer> result = mExecutor.submit(new Callable<Integer>() { @Override public Integer call() throws Exception { return fibc(20); } }); System.out.print("callable"+result.get()); } private static void futureTask() throws ExecutionException, InterruptedException { FutureTask<Integer> task=new FutureTask<Integer>(new Callable<Integer>() { @Override public Integer call() throws Exception { return fibc(20); } }); mExecutor.submit(task); //也可以和Runnable一样交给Thread来处理。 //Thread thread=new Thread(task); //thread.start(); System.out.print("futureTask"+task.get()); } //耗时操作 private static int fibc(int num){ if (num==0) return 0; if (num==1) return 1; return fibc(num-1)+fibc(num-2); } }
输出结果为:
runnable null;
callable 6765;
futureTask 6765;
上诉为非常简单的DEMO没有过多的注释,从中我们可以看出:
1、runnable是没有返回值的,callable和futureTask有返回值
2、runnable,callable是通过线程池返回的future来进行管理,无法自行管理;
而futureTask可以自行get返回值
3、其中get方法会阻塞,直到结果出来,才执行的打印语句。
相关文章推荐
- Android进阶——多线程系列之Thread、Runnable、Callable、Future、FutureTask
- 多线程中的Runnable、Callable、Future、FutureTask的作用
- 【Java多线程】-Callable,Future,FutureTask
- Android(Java)之多线程结果返回——Future 、FutureTask、Callable、Runnable
- Java多线程之 Callable、Future和FutureTask
- Java多线程21:多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask
- java多线程之Callable、Future和FutureTask
- java多线程系列(七)---Callable、Future和FutureTask
- JAVA---多线程之Callable与Future,FutureTask,及其简单应用
- 多线程 | 并发包中的Future、Callable、FutureTask 源码分析
- 多线程下的其它组件之CyclicBarrier、Callable、Future、FutureTask
- Java多线程之Executor、ExecutorService、Executors、Callable、Future与FutureTask
- Java多线程21:多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask
- java多线程系列(七)---Callable、Future和FutureTask
- 多线程(九)Callable、Future和FutureTask
- 多线程任务Callable与Future或FutureTask的使用
- 大话Android多线程(四) Callable、Future和FutureTask
- Java多线程研究06-带返回值的线程定义接口Callable以及Future,FutureTask的使用
- Java线程和多线程(十三)——Callable,Future,FutureTask
- Java多线程系列-多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask