标签:
Java并发编程之Callable, Runnable, Future, FutureTask
Java中存在Callable, Runnable, Future, FutureTask这几个与线程相关的类或接口, 下面来了解一下它们的作用和区别.
Callable和Runnable类似, 实现Callable和Runnable接口的类都是可以被其他线程运行的任务, Callable和Runnable主要有以下几点区别:
(1). Callable中声明的方法是call(), Runnable中声明的方法是run().
(2). Callable任务执行后可返回值, Runnable任务执行后没有返回值.
(3). call()方法可以抛出异常, run()方法不能抛出异常.
(4). 运行Callable任务可以拿到一个Future对象.
1 public interface Callable<V> { 2 /** 3 * Computes a result, or throws an exception if unable to do so. 4 * 5 * @return computed result 6 * @throws Exception if unable to compute a result 7 */ 8 V call() throws Exception; 9 } 10 11 12 public interface Runnable { 13 /** 14 * When an object implementing interface <code>Runnable</code> is used 15 * to create a thread, starting the thread causes the object‘s 16 * <code>run</code> method to be called in that separately executing 17 * thread. 18 * <p> 19 * The general contract of the method <code>run</code> is that it may 20 * take any action whatsoever. 21 * 22 * @see java.lang.Thread#run() 23 */ 24 public abstract void run(); 25 }
Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果、设置结果操作。可以通过get()方法获取执行结果, get()方法会阻塞,直到任务返回结果
public interface Future<V> { /** * 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 <tt>cancel</tt> is called, * this task should never run. If the task has already started, * then the <tt>mayInterruptIfRunning</tt> parameter determines * whether the thread executing this task should be interrupted in * an attempt to stop the task. * * <p>After this method returns, subsequent calls to {@link #isDone} will * always return <tt>true</tt>. Subsequent calls to {@link #isCancelled} * will always return <tt>true</tt> if this method returned <tt>true</tt>. * * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this * task should be interrupted; otherwise, in-progress tasks are allowed * to complete * @return <tt>false</tt> if the task could not be cancelled, * typically because it has already completed normally; * <tt>true</tt> otherwise */ boolean cancel(boolean mayInterruptIfRunning); /** * Returns <tt>true</tt> if this task was cancelled before it completed * normally. */ boolean isCancelled(); /** * Returns <tt>true</tt> if this task completed. * Completion may be due to normal termination, an exception, or * cancellation -- in all of these cases, this method will return * <tt>true</tt>. */ boolean isDone(); /** * Waits if necessary for the computation to complete, and then * retrieves its 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. */ V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }
下面依次解释每个方法的作用:
也就是说Future提供了三种功能:
1)判断任务是否完成;
2)能够中断任务;
3)能够获取任务执行结果。
因为Future只是一个接口,所以是无法直接用来创建对象使用的,因此就有了下面的FutureTask。
我们先来看一下FutureTask的实现:
public class FutureTask<V> implements RunnableFuture<V> { }
FutureTask类实现了RunnableFuture接口,我们看一下RunnableFuture接口的实现:
public interface RunnableFuture<V> extends Runnable, Future<V> { /** * Sets this Future to the result of its computation * unless it has been cancelled. */ void run(); }
可以看出RunnableFuture继承了Runnable接口和Future接口,而FutureTask实现了RunnableFuture接口。所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。
FutureTask提供了2个构造器:
public FutureTask(Callable<V> callable) { } public FutureTask(Runnable runnable, V result) { }
事实上,FutureTask是Future接口的一个唯一实现类
简单示例:
import java.util.concurrent.*; /** * Created by xinfengyao on 16-2-17. */ public class RunnableFutureTest { static ExecutorService executorService = Executors.newCachedThreadPool(); public static void main(String[] args) throws ExecutionException, InterruptedException { runnableDemo(); futureDemo(); } /** * Runnable无返回值 */ static void runnableDemo() { new Thread(new Runnable() { @Override public void run() { System.out.println("runnable demo: " + fibc(20)); } }).start(); } /** * 其中Runnable实现的是void run()方法,无返回值;Callable实现的是 V * call()方法,并且可以返回执行结果。其中Runnable可以提交给Thread来包装下 * ,直接启动一个线程来执行,而Callable则一般都是提交给ExecuteService来执行。 */ static void futureDemo() throws ExecutionException, InterruptedException { /** * 提交runnable则没有返回值, future没有数据 */ Future<?> result = executorService.submit(new Runnable() { @Override public void run() { fibc(20); } }); System.out.println("future result from runnable: " + result.get()); /** * 提交Callable, 有返回值, future中能够获取返回值 */ Future<Integer> result2 = executorService.submit(new Callable<Integer>() { @Override public Integer call() throws Exception { return fibc(20); } }); System.out.println("future result from callable: " + result2.get()); /** * FutureTask则是一个RunnableFuture<V>,既实现了Runnable又实现了Future<V>这两个接口, * 另外它还可以包装Runnable(实际上会转换为Callable)和Callable * <V>,所以一般来讲是一个复合体了,它可以通过Thread包装来直接执行,也可以提交给ExecuteService来执行 * ,并且还可以通过v get()返回执行结果,在线程体没有执行完成的时候,主线程一直阻塞等待,执行完则直接返回结果。 */ FutureTask<Integer> futureTask = new FutureTask<Integer>(new Callable<Integer>() { @Override public Integer call() throws Exception { return fibc(20); } }); // 提交futureTask executorService.submit(futureTask); System.out.println("future result from futureTask: " + futureTask.get()); } static int fibc(int n) { if (n==0 || n==1) { return n; } return fibc(n-1) + fibc(n-2); } }
Callable, Runnable, Future, FutureTask
标签:
原文地址:http://www.cnblogs.com/NewMan13/p/5196690.html