实现个简单的Future

版权声明:转载请注明作者 https://blog.csdn.net/myth_g/article/details/87890600

直接贴demo:

1.第一种用到CountDownLatch :

public class Main3 {

    @FunctionalInterface
    static interface Call<T> {
        T call() throws InterruptedException;
    }

    static class Client<T> {
        private T t;

        public T getT() {
            return t;
        }

        public void setT(T t) {
            this.t = t;
        }
    }

    static class Service<T> {

        private final CountDownLatch c = new CountDownLatch(1);

        private final Client<T> client = new Client<>();

        Service<T> submit(final Call<T> call) {
            new Thread(() -> {
                try {
                    client.setT(call.call());
                    c.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
            return this;
        }

        public T get() throws InterruptedException {
            c.await();
            return this.client.getT();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        long start = System.currentTimeMillis();
        Service<String> submit = new Service<String>().submit(() -> {
            Thread.sleep(3000);
            return "边做饭边等菜";
        });
        Thread.sleep(2000);
        System.out.println("买菜");
        String s = submit.get();
        System.out.println(s);
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }
}

结果:

买菜
边做饭边等菜
3041

2.第二种使用判断成员变量:

public class Main6 {

    @FunctionalInterface
    static interface Call<T> {
        T call() throws InterruptedException;
    }

    static class Client<T> {
        private T t;

        public T getT() {
            return t;
        }

        public void setT(T t) {
            this.t = t;
        }
    }

    static class Service<T> {

        private final Client<T> client = new Client<>();

        private volatile boolean flag;


        Service<T> submit(final Call<T> call) {
            new Thread(() -> {
                try {
                    //同步代码块要放在线程里
                    synchronized (this) {
                        client.setT(call.call());
                        flag = true;
                        this.notify();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();

            return this;
        }

        public T get() throws InterruptedException {
            synchronized (this) {
                if(!flag){
                    //线程等待释放,让出cpu占用
                    this.wait();
                }
                return this.client.getT();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        long start = System.currentTimeMillis();
        Service<String> submit = new Service<String>().submit(() -> {
            Thread.sleep(1500);
            return "边做饭边等菜";
        });
        Thread.sleep(500);
        System.out.println("买菜");
        String s = submit.get();
        System.out.println(s);
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }

}

其实这个思路就是:

先运行个线程,线程是没有返回值的.这时传入一个封装类,去接受线程里的结果.然后使用线程工具使得到结果方法和异步线程阻塞,改变执行顺序.

猜你喜欢

转载自blog.csdn.net/myth_g/article/details/87890600