本文转载自:http://blog.csdn.net/bboyfeiyu/article/details/24851847
Runnable
其中Runnable应该是我们最熟悉的接口,它只有一个run()函数,用于将耗时操作写在其中,该函数没有返回值。然后使用某个线程去执行该runnable即可实现多线程,Thread类在调用start()函数后就是执行的是Runnable的run()函数。Runnable的声明如下 :
1 public interface Runnable { 2 /** 3 * When an object implementing interface <code>Runnable</code> is used 4 * to create a thread, starting the thread causes the object's 5 * <code>run</code> method to be called in that separately executing 6 * thread. 7 * <p> 8 * 9 * @see java.lang.Thread#run() 10 */ 11 public abstract void run(); 12 }
Callable
Callable与Runnable的功能大致相似,Callable中有一个call()函数,但是call()函数有返回值,而Runnable的run()函数不能将结果返回给客户程序。Callable的声明如下 :
可以看到,这是一个泛型接口,call()函数返回的类型就是客户程序传递进来的V类型。
Future
Executor就是Runnable和Callable的调度容器,Future就是对于具体的Runnable或者Callable任务的执行结果进行
取消、查询是否完成、获取结果、设置结果操作。get方法会阻塞,直到任务返回结果(Future简介)。Future声明如下 :
1 /** 2 * @see FutureTask 3 * @see Executor 4 * @since 1.5 5 * @author Doug Lea 6 * @param <V> The result type returned by this Future's <tt>get</tt> method 7 */ 8 public interface Future<V> { 9 10 /** 11 * Attempts to cancel execution of this task. This attempt will 12 * fail if the task has already completed, has already been cancelled, 13 * or could not be cancelled for some other reason. If successful, 14 * and this task has not started when <tt>cancel</tt> is called, 15 * this task should never run. If the task has already started, 16 * then the <tt>mayInterruptIfRunning</tt> parameter determines 17 * whether the thread executing this task should be interrupted in 18 * an attempt to stop the task. * 19 */ 20 boolean cancel(boolean mayInterruptIfRunning); 21 22 /** 23 * Returns <tt>true</tt> if this task was cancelled before it completed 24 * normally. 25 */ 26 boolean isCancelled(); 27 28 /** 29 * Returns <tt>true</tt> if this task completed. 30 * 31 */ 32 boolean isDone(); 33 34 /** 35 * Waits if necessary for the computation to complete, and then 36 * retrieves its result. 37 * 38 * @return the computed result 39 */ 40 V get() throws InterruptedException, ExecutionException; 41 42 /** 43 * Waits if necessary for at most the given time for the computation 44 * to complete, and then retrieves its result, if available. 45 * 46 * @param timeout the maximum time to wait 47 * @param unit the time unit of the timeout argument 48 * @return the computed result 49 */ 50 V get(long timeout, TimeUnit unit) 51 throws InterruptedException, ExecutionException, TimeoutException; 52 }
FutureTask
FutureTask则是一个RunnableFuture<V>,而RunnableFuture实现了Runnbale又实现了Futrue<V>这两个接口,
另外它还可以包装Runnable和Callable<V>, 由构造函数注入依赖。
1 public FutureTask(Callable<V> callable) { 2 if (callable == null) 3 throw new NullPointerException(); 4 this.callable = callable; 5 this.state = NEW; // ensure visibility of callable 6 } 7 8 public FutureTask(Runnable runnable, V result) { 9 this.callable = Executors.callable(runnable, result); 10 this.state = NEW; // ensure visibility of callable 11 }
RunnableAdapter适配器
1 /** 2 * A callable that runs given task and returns given result 3 */ 4 static final class RunnableAdapter<T> implements Callable<T> { 5 final Runnable task; 6 final T result; 7 RunnableAdapter(Runnable task, T result) { 8 this.task = task; 9 this.result = result; 10 } 11 public T call() { 12 task.run(); 13 return result; 14 } 15 }
由于FutureTask实现了Runnable,因此它既可以通过Thread包装来直接执行,也可以提交给ExecuteService来执行。
并且还可以直接通过get()函数获取执行结果,该函数会阻塞,直到结果返回。因此FutureTask既是Future、
Runnable,又是包装了Callable( 如果是Runnable最终也会被转换为Callable ), 它是这两者的合体。
简单示例
1 package com.effective.java.concurrent.task; 2 3 import java.util.concurrent.Callable; 4 import java.util.concurrent.ExecutionException; 5 import java.util.concurrent.ExecutorService; 6 import java.util.concurrent.Executors; 7 import java.util.concurrent.Future; 8 import java.util.concurrent.FutureTask; 9 10 /** 11 * 12 * @author mrsimple 13 * 14 */ 15 public class RunnableFutureTask { 16 17 /** 18 * ExecutorService 19 */ 20 static ExecutorService mExecutor = Executors.newSingleThreadExecutor(); 21 22 /** 23 * 24 * @param args 25 */ 26 public static void main(String[] args) { 27 runnableDemo(); 28 futureDemo(); 29 } 30 31 /** 32 * runnable, 无返回值 33 */ 34 static void runnableDemo() { 35 36 new Thread(new Runnable() { 37 38 @Override 39 public void run() { 40 System.out.println("runnable demo : " + fibc(20)); 41 } 42 }).start(); 43 } 44 45 /** 46 * 其中Runnable实现的是void run()方法,无返回值;Callable实现的是 V 47 * call()方法,并且可以返回执行结果。其中Runnable可以提交给Thread来包装下 48 * ,直接启动一个线程来执行,而Callable则一般都是提交给ExecuteService来执行。 49 */ 50 static void futureDemo() { 51 try { 52 /** 53 * 提交runnable则没有返回值, future没有数据 54 */ 55 Future<?> result = mExecutor.submit(new Runnable() { 56 57 @Override 58 public void run() { 59 fibc(20); 60 } 61 }); 62 63 System.out.println("future result from runnable : " + result.get()); 64 65 /** 66 * 提交Callable, 有返回值, future中能够获取返回值 67 */ 68 Future<Integer> result2 = mExecutor.submit(new Callable<Integer>() { 69 @Override 70 public Integer call() throws Exception { 71 return fibc(20); 72 } 73 }); 74 75 System.out 76 .println("future result from callable : " + result2.get()); 77 78 /** 79 * FutureTask则是一个RunnableFuture<V>,即实现了Runnbale又实现了Futrue<V>这两个接口, 80 * 另外它还可以包装Runnable(实际上会转换为Callable)和Callable 81 * <V>,所以一般来讲是一个符合体了,它可以通过Thread包装来直接执行,也可以提交给ExecuteService来执行 82 * ,并且还可以通过v get()返回执行结果,在线程体没有执行完成的时候,主线程一直阻塞等待,执行完则直接返回结果。 83 */ 84 FutureTask<Integer> futureTask = new FutureTask<Integer>( 85 new Callable<Integer>() { 86 @Override 87 public Integer call() throws Exception { 88 return fibc(20); 89 } 90 }); 91 // 提交futureTask 92 mExecutor.submit(futureTask) ; 93 System.out.println("future result from futureTask : " 94 + futureTask.get()); 95 96 } catch (InterruptedException e) { 97 e.printStackTrace(); 98 } catch (ExecutionException e) { 99 e.printStackTrace(); 100 } 101 } 102 103 /** 104 * 效率底下的斐波那契数列, 耗时的操作 105 * 106 * @param num 107 * @return 108 */ 109 static int fibc(int num) { 110 if (num == 0) { 111 return 0; 112 } 113 if (num == 1) { 114 return 1; 115 } 116 return fibc(num - 1) + fibc(num - 2); 117 } 118 119 }