Java中的Runnable、Callable、Future、FutureTask的区别与示例(一)

2014-11-23 22:15:07 · 作者: · 浏览: 2

Java中存在Runnable、Callable、Future、FutureTask这几个与线程相关的类或者接口,在Java中也是比较重要的几个概念,我们通过下面的简单示例来了解一下它们的作用于区别。

Runnable

其中Runnable应该是我们最熟悉的接口,它只有一个run()函数,用于将耗时操作写在其中,该函数没有返回值。然后使用某个线程去执行该runnable即可实现多线程,Thread类在调用start()函数后就是执行的是Runnable的run()函数。Runnable的声明如下 :

public interface Runnable {
    /**
     * When an object implementing interface Runnable is used
     * to create a thread, starting the thread causes the object's
     * run method to be called in that separately executing
     * thread.
     * 

* * @see java.lang.Thread#run() */ public abstract void run(); }

Callable

Callable与Runnable的功能大致相似,Callable中有一个call()函数,但是call()函数有返回值,而Runnable的run()函数不能将结果返回给客户程序。Callable的声明如下 :

public interface Callable
  
    {
    /**
     * 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;
}
  
可以看到,这是一个泛型接口,call()函数返回的类型就是客户程序传递进来的V类型。

Future

Executor就是Runnable和Callable的调度容器,Future就是对于具体的Runnable或者Callable任务的执行结果进行

取消、查询是否完成、获取结果、设置结果操作。get方法会阻塞,直到任务返回结果(Future简介)。Future声明如下 :

/**
* @see FutureTask
 * @see Executor
 * @since 1.5
 * @author Doug Lea
 * @param 
  
    The result type returned by this Future's 
   get method
 */
public interface Future
   
     { /** * Attempts to cancel execution of this task. This attempt will * fail if the task has already completed, has already been cancelled, * or could not be cancelled for some other reason. If successful, * and this task has not started when 
    cancel is called, * this task should never run. If the task has already started, * then the 
    mayInterruptIfRunning parameter determines * whether the thread executing this task should be interrupted in * an attempt to stop the task. * */ boolean cancel(boolean mayInterruptIfRunning); /** * Returns 
    true if this task was cancelled before it completed * normally. */ boolean isCancelled(); /** * Returns 
    true if this task completed. * */ boolean isDone(); /** * Waits if necessary for the computation to complete, and then * retrieves its result. * * @return the computed result */ V get() throws InterruptedException, ExecutionException; /** * Waits if necessary for at most the given time for the computation * to complete, and then retrieves its result, if available. * * @param timeout the maximum time to wait * @param unit the time unit of the timeout argument * @return the computed result */ V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }
   
  

FutureTask

FutureTask则是一个RunnableFuture ,而RunnableFuture实现了Runnbale又实现了Futrue 这两个接口,

public class FutureTask
  
    implements RunnableFuture
   
  
RunnableFuture

public interface RunnableFuture
  
    extends Runnable, Future
   
     { /** * Sets this Future to the result of its computation * unless it has been cancelled. */ void run(); }
   
  

另外它还可以包装Runnable和Callable , 由构造函数注入依赖。

    public FutureTask(Callable
  
    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
    }
  
可以看到,Runnable注入会被Executors.callable()函数转换为Callable类型,即FutureTask最终都是执行Callable类型的任务。该适配函数的实现如下 :

    public static 
  
    Callable
   
     callable(Runnable task, T result) { if (task == null) throw new NullPo