Java8新特性 - Future

Java8新特性 - Future

package future;

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

public class FutureAction {

    public static void main(String[] args) {

        Future<String> future = invoke(() -> {
            try {
                Thread.sleep(10000);
                return "I am finished";
            } catch (InterruptedException e) {
                return "Error";
            }
        });
        System.out.println(future.get());
        System.out.println(future.get());
        System.out.println(future.get());

        while (!future.isDone()) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(future.get());
    }

    public static <T> Future<T> invoke(Callable<T> callable) {
        AtomicReference atomicReference = new AtomicReference();
        AtomicBoolean atomicBoolean = new AtomicBoolean(false);

        // 关键在于线程启动之后,程序就可以直接往下执行了,直接返回一个Future对象,只不过对象内相应的数据还没有,需要等待线程执行完成,future才有值可取。
        // 这种方式应用于异步回调场景最多。
        new Thread(() -> {
            T action = callable.action();
            atomicReference.set(action);
            atomicBoolean.set(true);
        }).start();

        Future<T> future = new Future<T>() {
            @Override
            public T get() {
                return (T) atomicReference.get();
            }

            @Override
            public boolean isDone() {
                return atomicBoolean.get();
            }
        };
        return future;
    }

    interface Future<T>{
        T get();

        boolean isDone();
    }

    interface Callable<T>{
        T action();
    }
}

执行结果:

 

JDK自带的Future,Callable使用:

 

基于事件回调方式:

package future;

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

public class FutureAction2 {

    public static void main(String[] args) {

        Future<String> future = invoke(() -> {
            try {
                Thread.sleep(3000);
                return "I am finished";
            } catch (InterruptedException e) {
                return "Error";
            }
        });
//        System.out.println(future.get());
//        System.out.println(future.get());
//        System.out.println(future.get());

        future.setCompletable(new Completable<String>() {
            @Override
            public void completable(String s) {
                try {
                    Thread.sleep(3000);
                    System.out.println("sleep 3s");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(s + "123");
            }

            @Override
            public void throwException(Throwable cause) {
                System.out.println(cause);
                cause.printStackTrace();
            }
        });

        System.out.println("........");
        System.out.println(future.get());
        System.out.println(future.get());

//        while (!future.isDone()) {
//            try {
//                Thread.sleep(10);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        }
//        System.out.println(future.get());
    }

    public static <T> Future<T> invoke(Callable<T> callable) {
        AtomicReference atomicReference = new AtomicReference();
        AtomicBoolean atomicBoolean = new AtomicBoolean(false);

        Future<T> future = new Future<T>() {
            private Completable<T> completable;

            @Override
            public T get() {
                return (T) atomicReference.get();
            }

            @Override
            public boolean isDone() {
                return atomicBoolean.get();
            }

            @Override
            public void setCompletable(Completable<T> completable) {
                this.completable = completable;
            }

            @Override
            public Completable<T> getCompletable() {
                return completable;
            }
        };

        new Thread(() -> {
            try {
                T action = callable.action();
                atomicReference.set(action);
                atomicBoolean.set(true);
                if (future.getCompletable() != null)
                    future.getCompletable().completable((String) action);
            } catch (Throwable cause) {
                future.getCompletable().throwException(cause);
            }
        }).start();

        return future;
    }

    interface Future<T> {
        T get();

        boolean isDone();

        void setCompletable(Completable<T> completable);

        Completable<T> getCompletable();
    }

    interface Callable<T> {
        T action();
    }

    interface Completable<T> {
        void completable(String s);

        void throwException(Throwable cause);
    }
}