十七、模拟Future

在这里插入图片描述


/**
 * Future模式
 * 模拟一个在没有锅和食材的情况下要进行烹饪的过程
 *
 * 1、Future代表:一个异步调用的未来的凭证,在做完其它事情之后   相当于JDK中的Future接口
 * 再往下必须要返回结果时可以拿着这个凭证去进行get我们想要的返回结果
 * 2、FutureTask代表:将调用逻辑和返回结果进行隔离      相当于JDK中的Callable接口
 * 3、FutureService:是桥接Future和FutureTask的作用,      相当于JDK中的线程池服务(ExecutorService)
 * 使Future不用知道FutureTask的具体逻辑,而FutureTask也不用知道有Future这个东西
 *
 * 调用者(client)只需要通过FutureService就可以完成自己的逻辑,不用关心其它
 *
 * @author xzq
 */
public class CallableAndFutureTest01 {

    public static void main(String[] args) throws InterruptedException {
//      String panResult = buyPan();
//      String foodResult = buyFood();
//      //使用同步的方式整个过程需要花费13秒的时间
//      System.out.println("开始烹饪!!!,把"+foodResult+"放进"+panResult+"里开始烹饪……");

        FutureService<String> futureService=new FutureService<>();
        Future<String> panFuture = futureService.submit(new FutureTask<String>(){

            @Override
            public String call() {
                try {
                    return buyPan();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                return null;
            }
        });
        String foodResult = buyFood();
        //使用异步的方式整个过程需要花费10秒的时间
        //……
        System.out.println("开始烹饪!!!,把"+foodResult+"放进"+panFuture.get()+"里开始烹饪……");
    }

    /**
     * 在苏宁易购上,网购一个锅
     * @throws InterruptedException
     */
    private static String buyPan() throws InterruptedException {
        System.out.println("打电话订购锅!");
        System.out.println("快递正在将锅运往我家的途中……");
        //需要花费10秒时间才能送到我家
        Thread.sleep(10_000);
        System.out.println("快递将锅送到我家,我已经收到并签收!");
        return "锅";
    }

    /**
     * 购买食材
     * @throws InterruptedException
     */
    private static String buyFood() throws InterruptedException {
        System.out.println("出门去菜市场购买食材……");
        //需要花费3秒时间才能买完食材回到家
        Thread.sleep(3_000);
        System.out.println("购买食材完毕回到家!");
        return "食材";
    }

    /**
     * 一个表示未来的事物的一个抽象
     * @author Peter
     */
    static interface Future<T>{

        /**
         * 获取结果方法
         * @return
         * @throws InterruptedException
         */
        T get() throws InterruptedException;
    }

    /**
     * 执行逻辑的抽象
     * @author Peter
     * @param <T>
     */
    static interface FutureTask<T>{
        /**
         * 逻辑执行方法
         * @return
         */
        T call();
    }

    /**
     * 桥接类
     * @author Peter
     * @param <T>
     */
    static class FutureService<T>{

        public  Future<T> submit(final FutureTask<T> task){
            final AsynFuture<T> asynFuture=new AsynFuture<>();
            new Thread(){
                //这里相当于购买锅后快递将锅送到家的过程
                @Override
                public void run() {
                    T result = task.call();
                    //得到结果后通知asynFuture已经完成了
                    asynFuture.done(result);
                }
            }.start();

            return asynFuture;
        }
    }

    /**
     * 异步Future实现类
     * @author Peter
     * @param <T>
     */
    static class AsynFuture<T> implements Future<T>{

        private volatile boolean isDone=false;

        private T result;

        public void done(T result){
            synchronized (this) {
                this.result=result;
                this.isDone=true;
                this.notifyAll();
            }
        }

        @Override
        public T get() throws InterruptedException {
            synchronized (this) {
                while(!isDone){
                    //没有完成就等待
                    this.wait();
                }
            }
            //完成了就把结果返回
            return result;
        }

    }

}


2、加入回调模式更加优化Future模式

/**
 *  加入回调模式更加优化Future模式
 *  前面阻塞的方式就是等于轮询的方式,这里采用回调方式是一种非阻塞方式
 * @author xzq
 */
public class CallableAndFutureTest02 {

    private static String panResult=null;

    public static void main(String[] args) throws InterruptedException {

        FutureService<String> futureService=new FutureService<>();
        //这里就不需要一个未来用于获取结果的凭证了
        futureService.submit(new FutureTask<String>(){

                                 @Override
                                 public String call() {
                                     try {
                                         return buyPan();
                                     } catch (InterruptedException e) {
                                         // TODO Auto-generated catch block
                                         e.printStackTrace();
                                     }
                                     return null;
                                 }
                             },
                //这里是送到家门口的快递取货箱默认我已签收
                new NoResultCallBack<String>() {
                    @Override
                    public void backResult(String result) {
                        panResult=result;
                    }
                });
        String foodResult = buyFood();
        //使用异步的方式整个过程需要花费10秒的时间
        if(panResult==null){
            //可以干别的事情
        }else{
            System.out.println("开始烹饪!!!,把"+foodResult+"放进"+panResult+"里开始烹饪……");

        }

    }



    /**
     * 在苏宁易购上,网购一个锅
     * @throws InterruptedException
     */
    private static String buyPan() throws InterruptedException {
        System.out.println("打电话订购锅!");
        System.out.println("快递正在将锅运往我家的途中……");
        //需要花费10秒时间才能送到我家
        Thread.sleep(10_000);
        System.out.println("快递将锅送到我家,我已经收到并签收!");
        return "锅";
    }

    /**
     * 购买食材
     * @throws InterruptedException
     */
    private static String buyFood() throws InterruptedException {
        System.out.println("出门去菜市场购买食材……");
        //需要花费3秒时间才能买完食材回到家
        Thread.sleep(3_000);
        System.out.println("购买食材完毕回到家!");
        return "食材";
    }

    /**
     * 一个表示未来的事物的一个抽象
     * @author Peter
     */
    static interface Future<T>{

        /**
         * 获取结果方法
         * @return
         * @throws InterruptedException
         */
        T get() throws InterruptedException;
    }

    /**
     * 执行逻辑的抽象
     * @author Peter
     * @param <T>
     */
    static interface FutureTask<T>{
        /**
         * 逻辑执行方法
         * @return
         */
        T call();
    }

    /**
     * 桥接类
     * @author Peter
     * @param <T>
     */
    static class FutureService<T>{

        public  Future<T> submit(final FutureTask<T> task,final NoResultCallBack<T> callBack){
            final AsynFuture<T> asynFuture=new AsynFuture<>();
            new Thread(){
                //这里相当于购买锅后快递将锅送到家的过程
                @Override
                public void run() {
                    T result = task.call();
                    //得到结果后通知asynFuture已经完成了
                    asynFuture.done(result);
                    //并且将结果返回给调用方
                    callBack.backResult(result);
                }
            }.start();

            return asynFuture;
        }
    }

    /**
     * 回调接口
     * @author Peter
     * @param <V>
     */
    static interface NoResultCallBack<V>{

        void backResult(V result);

    }

    /**
     * 异步Future实现类
     * @author Peter
     * @param <T>
     */
    static class AsynFuture<T> implements Future<T>{

        private volatile boolean isDone=false;

        private T result;

        public void done(T result){
            synchronized (this) {
                this.result=result;
                this.isDone=true;
                this.notifyAll();
            }
        }

        @Override
        public T get() throws InterruptedException {
            synchronized (this) {
                while(!isDone){
                    //没有完成就等待
                    this.wait();
                }
            }
            //完成了就把结果返回
            return result;
        }
    }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值