- 浏览: 77612 次
- 性别:
- 来自: 上海
文章分类
最新评论
Java中的Callable、Future、FutureTask、Runnable的区别与示例
Java中存在Runnable、Callable、Future、FutureTask这几个与线程相关的类或者接口,在Java中也是比较重要的几个概念,我们通过下面的简单示例来了解一下它们的作用于区别。
Runnable
其中Runnable应该是我们最熟悉的接口,它只有一个run()函数,用于将耗时操作写在其中,该函数没有返回值。然后使用某个线程去执行该runnable即可实现多线程,Thread类在调用start()函数后就是执行的是Runnable的run()函数。Runnable的声明如下 :
- publicinterfaceRunnable{
- /**
- *Whenanobjectimplementinginterface<code>Runnable</code>isused
- *tocreateathread,startingthethreadcausestheobject's
- *<code>run</code>methodtobecalledinthatseparatelyexecuting
- *thread.
- *<p>
- *
- *@seejava.lang.Thread#run()
- */
- publicabstractvoidrun();
- }
Callable
Callable与Runnable的功能大致相似,Callable中有一个call()函数,但是call()函数有返回值,而Runnable的run()函数不能将结果返回给客户程序。Callable的声明如下 :
- publicinterfaceCallable<V>{
- /**
- *Computesaresult,orthrowsanexceptionifunabletodoso.
- *
- *@returncomputedresult
- *@throwsExceptionifunabletocomputearesult
- */
- Vcall()throwsException;
- }
Future
Executor就是Runnable和Callable的调度容器,Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果、设置结果操作。get方法会阻塞,直到任务返回结果(Future简介)。Future声明如下 :
- /**
- *@seeFutureTask
- *@seeExecutor
- *@since1.5
- *@authorDougLea
- *@param<V>TheresulttypereturnedbythisFuture's<tt>get</tt>method
- */
- publicinterfaceFuture<V>{
- /**
- *Attemptstocancelexecutionofthistask.Thisattemptwill
- *failifthetaskhasalreadycompleted,hasalreadybeencancelled,
- *orcouldnotbecancelledforsomeotherreason.Ifsuccessful,
- *andthistaskhasnotstartedwhen<tt>cancel</tt>iscalled,
- *thistaskshouldneverrun.Ifthetaskhasalreadystarted,
- *thenthe<tt>mayInterruptIfRunning</tt>parameterdetermines
- *whetherthethreadexecutingthistaskshouldbeinterruptedin
- *anattempttostopthetask.*
- */
- booleancancel(booleanmayInterruptIfRunning);
- /**
- *Returns<tt>true</tt>ifthistaskwascancelledbeforeitcompleted
- *normally.
- */
- booleanisCancelled();
- /**
- *Returns<tt>true</tt>ifthistaskcompleted.
- *
- */
- booleanisDone();
- /**
- *Waitsifnecessaryforthecomputationtocomplete,andthen
- *retrievesitsresult.
- *
- *@returnthecomputedresult
- */
- Vget()throwsInterruptedException,ExecutionException;
- /**
- *Waitsifnecessaryforatmostthegiventimeforthecomputation
- *tocomplete,andthenretrievesitsresult,ifavailable.
- *
- *@paramtimeoutthemaximumtimetowait
- *@paramunitthetimeunitofthetimeoutargument
- *@returnthecomputedresult
- */
- Vget(longtimeout,TimeUnitunit)
- throwsInterruptedException,ExecutionException,TimeoutException;
- }
FutureTask
FutureTask则是一个RunnableFuture<V>,而RunnableFuture实现了Runnbale又实现了Futrue<V>这两个接口,
- publicclassFutureTask<V>implementsRunnableFuture<V>
- publicinterfaceRunnableFuture<V>extendsRunnable,Future<V>{
- /**
- *SetsthisFuturetotheresultofitscomputation
- *unlessithasbeencancelled.
- */
- voidrun();
- }
另外它还可以包装Runnable和Callable<V>, 由构造函数注入依赖。
- publicFutureTask(Callable<V>callable){
- if(callable==null)
- thrownewNullPointerException();
- this.callable=callable;
- this.state=NEW;//ensurevisibilityofcallable
- }
- publicFutureTask(Runnablerunnable,Vresult){
- this.callable=Executors.callable(runnable,result);
- this.state=NEW;//ensurevisibilityofcallable
- }
- publicstatic<T>Callable<T>callable(Runnabletask,Tresult){
- if(task==null)
- thrownewNullPointerException();
- returnnewRunnableAdapter<T>(task,result);
- }
- /**
- *Acallablethatrunsgiventaskandreturnsgivenresult
- */
- staticfinalclassRunnableAdapter<T>implementsCallable<T>{
- finalRunnabletask;
- finalTresult;
- RunnableAdapter(Runnabletask,Tresult){
- this.task=task;
- this.result=result;
- }
- publicTcall(){
- task.run();
- returnresult;
- }
- }
由于FutureTask实现了Runnable,因此它既可以通过Thread包装来直接执行,也可以提交给ExecuteService来执行。
并且还可以直接通过get()函数获取执行结果,该函数会阻塞,直到结果返回。因此FutureTask既是Future、Runnable,又是包装了Callable( 如果是Runnable最终也会被转换为Callable ), 它是这两者的合体。
简单示例
- packagecom.effective.java.concurrent.task;
- importjava.util.concurrent.Callable;
- importjava.util.concurrent.ExecutionException;
- importjava.util.concurrent.ExecutorService;
- importjava.util.concurrent.Executors;
- importjava.util.concurrent.Future;
- importjava.util.concurrent.FutureTask;
- /**
- *
- *@authormrsimple
- *
- */
- publicclassRunnableFutureTask{
- /**
- *ExecutorService
- */
- staticExecutorServicemExecutor=Executors.newSingleThreadExecutor();
- /**
- *
- *@paramargs
- */
- publicstaticvoidmain(String[]args){
- runnableDemo();
- futureDemo();
- }
- /**
- *runnable,无返回值
- */
- staticvoidrunnableDemo(){
- newThread(newRunnable(){
- @Override
- publicvoidrun(){
- System.out.println("runnabledemo:"+fibc(20));
- }
- }).start();
- }
- /**
- *其中Runnable实现的是voidrun()方法,无返回值;Callable实现的是V
- *call()方法,并且可以返回执行结果。其中Runnable可以提交给Thread来包装下
- *,直接启动一个线程来执行,而Callable则一般都是提交给ExecuteService来执行。
- */
- staticvoidfutureDemo(){
- try{
- /**
- *提交runnable则没有返回值,future没有数据
- */
- Future<?>result=mExecutor.submit(newRunnable(){
- @Override
- publicvoidrun(){
- fibc(20);
- }
- });
- System.out.println("futureresultfromrunnable:"+result.get());
- /**
- *提交Callable,有返回值,future中能够获取返回值
- */
- Future<Integer>result2=mExecutor.submit(newCallable<Integer>(){
- @Override
- publicIntegercall()throwsException{
- returnfibc(20);
- }
- });
- System.out
- .println("futureresultfromcallable:"+result2.get());
- /**
- *FutureTask则是一个RunnableFuture<V>,即实现了Runnbale又实现了Futrue<V>这两个接口,
- *另外它还可以包装Runnable(实际上会转换为Callable)和Callable
- *<V>,所以一般来讲是一个符合体了,它可以通过Thread包装来直接执行,也可以提交给ExecuteService来执行
- *,并且还可以通过vget()返回执行结果,在线程体没有执行完成的时候,主线程一直阻塞等待,执行完则直接返回结果。
- */
- FutureTask<Integer>futureTask=newFutureTask<Integer>(
- newCallable<Integer>(){
- @Override
- publicIntegercall()throwsException{
- returnfibc(20);
- }
- });
- //提交futureTask
- mExecutor.submit(futureTask);
- System.out.println("futureresultfromfutureTask:"
- +futureTask.get());
- }catch(InterruptedExceptione){
- e.printStackTrace();
- }catch(ExecutionExceptione){
- e.printStackTrace();
- }
- }
- /**
- *效率底下的斐波那契数列,耗时的操作
- *
- *@paramnum
- *@return
- */
- staticintfibc(intnum){
- if(num==0){
- return0;
- }
- if(num==1){
- return1;
- }
- returnfibc(num-1)+fibc(num-2);
- }
- }
输出结果
Java中存在Runnable、Callable、Future、FutureTask这几个与线程相关的类或者接口,在Java中也是比较重要的几个概念,我们通过下面的简单示例来了解一下它们的作用于区别。
Runnable
其中Runnable应该是我们最熟悉的接口,它只有一个run()函数,用于将耗时操作写在其中,该函数没有返回值。然后使用某个线程去执行该runnable即可实现多线程,Thread类在调用start()函数后就是执行的是Runnable的run()函数。Runnable的声明如下 :
- publicinterfaceRunnable{
- /**
- *Whenanobjectimplementinginterface<code>Runnable</code>isused
- *tocreateathread,startingthethreadcausestheobject's
- *<code>run</code>methodtobecalledinthatseparatelyexecuting
- *thread.
- *<p>
- *
- *@seejava.lang.Thread#run()
- */
- publicabstractvoidrun();
- }
Callable
Callable与Runnable的功能大致相似,Callable中有一个call()函数,但是call()函数有返回值,而Runnable的run()函数不能将结果返回给客户程序。Callable的声明如下 :
- publicinterfaceCallable<V>{
- /**
- *Computesaresult,orthrowsanexceptionifunabletodoso.
- *
- *@returncomputedresult
- *@throwsExceptionifunabletocomputearesult
- */
- Vcall()throwsException;
- }
Future
Executor就是Runnable和Callable的调度容器,Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果、设置结果操作。get方法会阻塞,直到任务返回结果(Future简介)。Future声明如下 :
- /**
- *@seeFutureTask
- *@seeExecutor
- *@since1.5
- *@authorDougLea
- *@param<V>TheresulttypereturnedbythisFuture's<tt>get</tt>method
- */
- publicinterfaceFuture<V>{
- /**
- *Attemptstocancelexecutionofthistask.Thisattemptwill
- *failifthetaskhasalreadycompleted,hasalreadybeencancelled,
- *orcouldnotbecancelledforsomeotherreason.Ifsuccessful,
- *andthistaskhasnotstartedwhen<tt>cancel</tt>iscalled,
- *thistaskshouldneverrun.Ifthetaskhasalreadystarted,
- *thenthe<tt>mayInterruptIfRunning</tt>parameterdetermines
- *whetherthethreadexecutingthistaskshouldbeinterruptedin
- *anattempttostopthetask.*
- */
- booleancancel(booleanmayInterruptIfRunning);
- /**
- *Returns<tt>true</tt>ifthistaskwascancelledbeforeitcompleted
- *normally.
- */
- booleanisCancelled();
- /**
- *Returns<tt>true</tt>ifthistaskcompleted.
- *
- */
- booleanisDone();
- /**
- *Waitsifnecessaryforthecomputationtocomplete,andthen
- *retrievesitsresult.
- *
- *@returnthecomputedresult
- */
- Vget()throwsInterruptedException,ExecutionException;
- /**
- *Waitsifnecessaryforatmostthegiventimeforthecomputation
- *tocomplete,andthenretrievesitsresult,ifavailable.
- *
- *@paramtimeoutthemaximumtimetowait
- *@paramunitthetimeunitofthetimeoutargument
- *@returnthecomputedresult
- */
- Vget(longtimeout,TimeUnitunit)
- throwsInterruptedException,ExecutionException,TimeoutException;
- }
FutureTask
FutureTask则是一个RunnableFuture<V>,而RunnableFuture实现了Runnbale又实现了Futrue<V>这两个接口,
- publicclassFutureTask<V>implementsRunnableFuture<V>
- publicinterfaceRunnableFuture<V>extendsRunnable,Future<V>{
- /**
- *SetsthisFuturetotheresultofitscomputation
- *unlessithasbeencancelled.
- */
- voidrun();
- }
另外它还可以包装Runnable和Callable<V>, 由构造函数注入依赖。
- publicFutureTask(Callable<V>callable){
- if(callable==null)
- thrownewNullPointerException();
- this.callable=callable;
- this.state=NEW;//ensurevisibilityofcallable
- }
- publicFutureTask(Runnablerunnable,Vresult){
- this.callable=Executors.callable(runnable,result);
- this.state=NEW;//ensurevisibilityofcallable
- }
- publicstatic<T>Callable<T>callable(Runnabletask,Tresult){
- if(task==null)
- thrownewNullPointerException();
- returnnewRunnableAdapter<T>(task,result);
- }
- /**
- *Acallablethatrunsgiventaskandreturnsgivenresult
- */
- staticfinalclassRunnableAdapter<T>implementsCallable<T>{
- finalRunnabletask;
- finalTresult;
- RunnableAdapter(Runnabletask,Tresult){
- this.task=task;
- this.result=result;
- }
- publicTcall(){
- task.run();
- returnresult;
- }
- }
由于FutureTask实现了Runnable,因此它既可以通过Thread包装来直接执行,也可以提交给ExecuteService来执行。
并且还可以直接通过get()函数获取执行结果,该函数会阻塞,直到结果返回。因此FutureTask既是Future、Runnable,又是包装了Callable( 如果是Runnable最终也会被转换为Callable ), 它是这两者的合体。
简单示例
- packagecom.effective.java.concurrent.task;
- importjava.util.concurrent.Callable;
- importjava.util.concurrent.ExecutionException;
- importjava.util.concurrent.ExecutorService;
- importjava.util.concurrent.Executors;
- importjava.util.concurrent.Future;
- importjava.util.concurrent.FutureTask;
- /**
- *
- *@authormrsimple
- *
- */
- publicclassRunnableFutureTask{
- /**
- *ExecutorService
- */
- staticExecutorServicemExecutor=Executors.newSingleThreadExecutor();
- /**
- *
- *@paramargs
- */
- publicstaticvoidmain(String[]args){
- runnableDemo();
- futureDemo();
- }
- /**
- *runnable,无返回值
- */
- staticvoidrunnableDemo(){
- newThread(newRunnable(){
- @Override
- publicvoidrun(){
- System.out.println("runnabledemo:"+fibc(20));
- }
- }).start();
- }
- /**
- *其中Runnable实现的是voidrun()方法,无返回值;Callable实现的是V
- *call()方法,并且可以返回执行结果。其中Runnable可以提交给Thread来包装下
- *,直接启动一个线程来执行,而Callable则一般都是提交给ExecuteService来执行。
- */
- staticvoidfutureDemo(){
- try{
- /**
- *提交runnable则没有返回值,future没有数据
- */
- Future<?>result=mExecutor.submit(newRunnable(){
- @Override
- publicvoidrun(){
- fibc(20);
- }
- });
- System.out.println("futureresultfromrunnable:"+result.get());
- /**
- *提交Callable,有返回值,future中能够获取返回值
- */
- Future<Integer>result2=mExecutor.submit(newCallable<Integer>(){
- @Override
- publicIntegercall()throwsException{
- returnfibc(20);
- }
- });
- System.out
- .println("futureresultfromcallable:"+result2.get());
- /**
- *FutureTask则是一个RunnableFuture<V>,即实现了Runnbale又实现了Futrue<V>这两个接口,
- *另外它还可以包装Runnable(实际上会转换为Callable)和Callable
- *<V>,所以一般来讲是一个符合体了,它可以通过Thread包装来直接执行,也可以提交给ExecuteService来执行
- *,并且还可以通过vget()返回执行结果,在线程体没有执行完成的时候,主线程一直阻塞等待,执行完则直接返回结果。
- */
- FutureTask<Integer>futureTask=newFutureTask<Integer>(
- newCallable<Integer>(){
- @Override
- publicIntegercall()throwsException{
- returnfibc(20);
- }
- });
- //提交futureTask
- mExecutor.submit(futureTask);
- System.out.println("futureresultfromfutureTask:"
- +futureTask.get());
- }catch(InterruptedExceptione){
- e.printStackTrace();
- }catch(ExecutionExceptione){
- e.printStackTrace();
- }
- }
- /**
- *效率底下的斐波那契数列,耗时的操作
- *
- *@paramnum
- *@return
- */
- staticintfibc(intnum){
- if(num==0){
- return0;
- }
- if(num==1){
- return1;
- }
- returnfibc(num-1)+fibc(num-2);
- }
- }
输出结果
相关推荐
Java使用Callable和Future创建线程操作示例主要介绍了Java使用Callable和Future创建线程操作,结合实例形式分析了java使用Callable接口和Future类创建线程的相关操作技巧与注意事项。 首先,Java 5开始,Java提供了...
`Future`、`FutureTask`、`Callable`和`Runnable`是Java并发编程中的核心接口和类,它们在Android开发中同样有着广泛的应用。下面将详细介绍这些概念以及它们如何协同工作。 1. `Runnable`: 这是Java中最基础的多...
2. 创建FutureTask实例:FutureTask是Java并发包(java.util.concurrent)中的一个类,它是一个可以被取消的任务,同时也是一个实现了Runnable接口的Future。FutureTask提供了对Callable结果的访问和管理,包括获取...
为了解决这个问题,Java提供了`Callable`接口和`FutureTask`类,它们是实现多线程返回值的关键工具。 `Callable`接口类似于`Runnable`,但比它功能更强大。`Callable`接口中的`call()`方法可以返回一个结果,并且...
在Java并发编程中,通常我们会使用`ExecutorService`来提交任务,而`Future`和`FutureTask`就是与这些任务交互的关键。 首先,`Future`是一个接口,它提供了一种机制来检查异步计算是否完成,以及在计算完成后获取...
Callable接口与Runnable接口类似,但它具有一个泛型方法`call()`,该方法在执行时会返回一个结果,并可能抛出异常。Callable接口的定义如下: ```java public interface Callable<V> { V call() throws Exception;...
Java 多线程 Callable 接口实现代码示例 Java 多线程编程中,创建线程有多种方式,其中一种便是实现 Callable 接口。Callable 接口是一个函数式接口,定义了一个 call 方法,该方法可以抛出异常并返回结果。与 ...
FutureTask类的内部包含一个Callable,并且可以接受Callable和Runnable作为构造函数,例如: ```java public FutureTask(Callable<V> callable) { if (callable == null) throw new NullPointerException(); this...
在Java多线程编程中,CyclicBarrier、Callable、Future和FutureTask是四个重要的组件,它们各自提供了不同的功能,帮助开发者更好地管理和协调并发任务。接下来,我们将深入探讨这些组件的特性和使用方法。 首先,...
总之,`FutureTask`是Java并发编程中用于异步计算的一个强大工具,它结合了`Runnable`和`Callable`的优点,提供了任务执行状态的检查以及结果的获取。理解和熟练使用`FutureTask`对于编写高效并发程序至关重要。在...
今天,我们将详细介绍Java concurrency线程池之Callable和Future,这两个组件在Java并发编程中扮演着重要的角色。 Callable Callable是一个接口,它只包含一个call()方法。Callable是一个返回结果并且可能抛出异常...
* Java中的Runnable、Callable、Future、FutureTask的区别与示例 * Java程序死锁问题原理及解决方案 * 线程锁技术 * 定时器、互斥、同步通信技术 * 多个线程之间共享数据的方式探討 * 使用JDK5中同步技术的3个面试题...
本文将深入探讨如何利用Java提供的`Runnable`与`Callable`接口配合`Future`或`FutureTask`来实现这一功能。 #### 一、基础知识回顾 在开始之前,我们先简要回顾一下`Runnable`和`Callable`这两个接口的基本概念: ...
在Java并发编程中,FutureTask扮演着至关重要的角色,它是实现异步计算的关键组件。本文将深入探讨FutureTask的原理和用法,帮助开发者更好地理解和利用这个强大的工具。 一、Future接口与FutureTask概述 Future...
Java 中创建线程主要有三种方式:继承 Thread 类创建线程类、通过 Runnable 接口创建线程类、通过 Callable 和 Future 创建线程。 继承 Thread 类创建线程类 继承 Thread 类创建线程类是 Java 中最基本的线程创建...
在Java编程中,"长时间运行任务式...在压缩包文件`jobTask2`中,可能包含了示例代码或教程,用于演示如何在Java中实现多线程任务式处理。通过学习和实践这些内容,开发者可以深入理解并掌握Java多线程编程的核心技术。
在IT行业中,多线程是程序设计中的一个重要概念,特别是在Java这种支持多线程操作的编程语言中。标题“Equ中多线程实现方式.rar”表明这是一个关于在Java环境中使用多线程进行路径规划的实践案例。从描述中反复提到...
在Java中,`FutureTask`是`Future`的一个常见实现,它同时实现了`Runnable`接口,因此可以被`ExecutorService`提交执行。此外,`ExecutorService`的一些submit()方法会返回实现了`Future`接口的对象,如`Future...
示例代码中,创建了一个`FutureTask<String> cookTask`,它的构造函数接收一个Callable对象,模拟做饭的过程。当调用`cookTask.get()`时,如果任务已完成,则返回结果;否则,主线程会被阻塞,直到任务完成。在这个...
这通常涉及到Java并发框架中的`Future`和`FutureTask`类。 `Future`接口在`java.util.concurrent`包中,它代表一个异步计算的结果。通过`Future`,我们可以检查计算是否完成,取消计算,甚至获取计算的结果。但是,...