標籤:ace out pos logs stat owa 線程 調用 es2017
類圖:
先看各自的源碼:
public interface Runnable { public abstract void run();}
publicclass Thread implements Runnable { /* What will be run. */ private Runnable target;}
Thread與Runnable其實是一個裝飾器模式。
public interface Callable<V> { V call() throws Exception;}
public interface Future<V> { boolean cancel(boolean mayInterruptIfRunning); boolean isCancelled(); boolean isDone(); V get() throws InterruptedException, ExecutionException; V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;}
public interface RunnableFuture<V> extends Runnable, Future<V> { void run();}
public class FutureTask<V> implements RunnableFuture<V> { /** The underlying callable; nulled out after running */ private Callable<V> callable; /** The result to return or exception to throw from get() */ private Object outcome; public void run() { if (state != NEW || !UNSAFE.compareAndSwapObject(this, runnerOffset, null, Thread.currentThread())) return; try { Callable<V> c = callable; if (c != null && state == NEW) { V result; boolean ran; try { result = c.call(); ran = true; } catch (Throwable ex) { result = null; ran = false; setException(ex); } if (ran) set(result); } } finally { // runner must be non-null until state is settled to // prevent concurrent calls to run() runner = null; // state must be re-read after nulling runner to prevent // leaked interrupts int s = state; if (s >= INTERRUPTING) handlePossibleCancellationInterrupt(s); } }}
從類的結構來看:
Runnable,Callable,Future介面本是互相獨立的,沒有直接的關係。
而Thread的一系列建構函式需要的是Runnable對象,所以Callable對象並不適合Thread建構函式,而是藉助於FutureTask這個類,該類實現具有Future和Runnable介面能力的類,同時組合Callable對象,FutureTask在run()方法中調用Callable的call()方法,這是個典型的適配器模式:
Runable是個目標介面,定義了Thread所需的介面;
Callable是被適配介面,定義了一個已經存在的介面方法call()
FutureTask是個適配器類,作為一個轉換器,將Runnable和Callable適配,適配器類是適配器模式的核心,它通過實現RunnableFuture和組合Callable使得兩者產生關係。
多線程-Thread,Runnable,Callable,Future,RunnableFuture,FutureTask