public static <T> Callable<T> callable(Runnable task, T result) { if (task == null) throw new NullPointerException(); return new RunnableAdapter<T>(task, result); }
public static Callable<Object> callable(Runnable task) { if (task == null) throw new NullPointerException(); return new RunnableAdapter<Object>(task, null); }
在 Java 1.5 后引入了 Callable 和 Future 使得以上问题能够被优雅的解决。
2. Callable 源代码
1 2 3
public interface Callable<V> { V call() throws Exception; }
可以在 Callable 的实现类中声明返回的数据类型,也可以抛出异常。
1 2 3 4 5 6 7 8 9 10 11
public class CallableTask implements Callable<String> {
public interface Future<V> { boolean cancel(boolean mayInterruptIfRunning); /** * Returns {@code true} if this task was cancelled before it completed * normally. */ boolean isCancelled(); /** * Returns {@code true} if this task completed. */ 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; }
public class FutureTask<V> implements RunnableFuture<V> { ... ... ... }
public interface RunnableFuture<V> extends Runnable, Future<V> { /** * Sets this Future to the result of its computation * unless it has been cancelled. */ void run(); }
// FutureTask#get() public V get() throws InterruptedException, ExecutionException { int s = state; if (s <= COMPLETING) s = awaitDone(false, 0L); return report(s); }
private int awaitDone(boolean timed, long nanos) throws InterruptedException { final long deadline = timed ? System.nanoTime() + nanos : 0L; WaitNode q = null; boolean queued = false; for (;;) { //最终返回状态,如果状态为完成,则执行 report(s) return state; } }
public void run() { try { Callable<V> c = callable; if (c != null && state == NEW) { V result; boolean ran; try { // 执行 call 方法,最终执行相应的操作,置位状态 result = c.call(); ran = true; } catch (Throwable ex) { result = null; ran = false; setException(ex); } if (ran) set(result); } } finally { int s = state; if (s >= INTERRUPTING) handlePossibleCancellationInterrupt(s); } }