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可以看到,这是一个泛型接口,call()函数返回的类型就是客户程序传递进来的V类型。{ /** * 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; }
Future
Executor就是Runnable和Callable的调度容器,Future就是对于具体的Runnable或者Callable任务的执行结果进行
取消、查询是否完成、获取结果、设置结果操作。get方法会阻塞,直到任务返回结果(Future简介)。Future声明如下 :
/** * @see FutureTask * @see Executor * @since 1.5 * @author Doug Lea * @paramThe 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
public class FutureTaskRunnableFutureimplements RunnableFuture
public interface RunnableFutureextends Runnable, Future { /** * Sets this Future to the result of its computation * unless it has been cancelled. */ void run(); }
另外它还可以包装Runnable和Callable
public FutureTask(Callable可以看到,Runnable注入会被Executors.callable()函数转换为Callable类型,即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 }
public staticCallable callable(Runnable task, T result) { if (task == null) throw new NullPo