Java那点事——异步
jopen
9年前
在JDK1.6提供了Future,FutureTask,ExecutorService等用于支持异步编程,但是Future,FutureTask没有提供callback机制,只能主动轮询,通过get去获取结果。
Guava的ListenableFuture对此做了扩展,支持callback机制。
就callback机制的扩展而言,也并不复杂。看看ListenableFuture与ListenableFutureTask:
public interface ListenableFuture extends Future { void addListener(Runnable listener, Executor executor); } public class ListenableFutureTask extends FutureTask implements ListenableFuture { // The execution list to hold our listeners. private final ExecutionList executionList = new ExecutionList(); //……… @Override public void addListener(Runnable listener, Executor exec) { executionList.add(listener, exec); } /** * Internal implementation detail used to invoke the listeners. */ @Override protected void done() { executionList.execute(); } }
callback通过addListener添加,通过override FutureTask的done()函数实现回调。 查看FutureTask会在Task执行完以后调用done()函数,如:
/** * Removes and signals all waiting threads, invokes done(), and * nulls out callable. */ private void finishCompletion() { // assert state > COMPLETING; for (WaitNode q; (q = waiters) != null;) { if (UNSAFE.compareAndSwapObject(this, waitersOffset, q, null)) { for (;;) { Thread t = q.thread; if (t != null) { q.thread = null; LockSupport.unpark(t); } WaitNode next = q.next; if (next == null) break; q.next = null; // unlink to help gc q = next; } break; } } done(); callable = null; // to reduce footprint }
与JDK一样,ListenableFuture需要通过ExecutorService创建,Guava定义了对应的ExecutorService,并提供MoreExecutors作为工具类,其中实现了ListeningDecorator与ScheduledListeningDecorator,它们都是对应的JDK ExecutorService的装饰。MoreExecutors提供的工具api非常很多,需要细细瞧瞧。
1.8版本开始,JDK也开始提供了一些更好支持异步编程的Future,典型的有CompletableFuture.
</div>