在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.
如果未说明,本Blog中文章皆为原创文章,请尊重他人劳动,转载请注明:转载自jmatrix
本文链接地址: Java那点事——异步
(注:一般引用了,我都会添加引用,如果有侵权的请联系我)
来自: http://www.jmatrix.org/java/1102.html |