Java异步任务中Future的实现

从netty中学习,首先截取netty中关于Promise和Future的继承关系图,如下。本文首先剖析下图中的四个类,然后自己设计Future。

java Future

public interface Future<V> {
    boolean cancel(boolean var1);
    boolean isCancelled();
    boolean isDone();
    V get() throws InterruptedException, ExecutionException;
    V get(long var1, TimeUnit var3) throws InterruptedException, ExecutionException, TimeoutException;
}

java的Future接口很简单,取消、阻塞等待完成、检查是否被取消或者完成。java中对Future最直接的实现是FutureTask,如下是一段代码展示如何使用FutureTask。

        ExecutorService pool=Executors.newFixedThreadPool(4);
        Callable<String> callable=()->{
            System.out.println("run");
            return new String("done");
        };
        //由callable创建FutureTask
        FutureTask<String> task=new FutureTask(callable);
        //线程池执行任务
        pool.execute(task);
        //等待执行完毕
        System.out.println(task.get()); //"done"
        System.out.println(task.isDone()); //true

因为java的future本身很简单,Netty中的Future继承java Future后增加了几个方法,我比较关注的是addListener这个方法。在使用Java Future时,我们使用Excutors框架提交任务后,只能get()来阻塞等待,或get(timeout)来轮询等待。如果增加了addListener方法,那么就可以在task执行完毕后,自动地调用Listener的方法,真正实现异步性。

下面就来看看的Future怎么实现addListener

addListener

Github地址

测试类

public class Main {
    public static void main(String[] args) {
        ExecutorService pool = Executors.newFixedThreadPool(1);
        FutureListener listener = (someFutureTask -> {
            System.out.println("任务完成");
            System.out.println("结果是:"+someFutureTask.get0());
        });
        SomeFutureTask<String> someFutureTask =
                new SomeFutureTask<String>(() -> "done").addListener(listener); // 增加listener
        pool.execute(someFutureTask);
        pool.execute(someFutureTask);
        pool.execute(someFutureTask);
        // 关闭线程池
//        pool.shutdownNow();
    }
}