Future-设计模式

Posted by 麦子 on Thursday, 2019年12月05日

[TOC]

转载地址:https://www.cnblogs.com/liang1101/p/6476698.html

Future模式

Future模式的核心在于:去除了主函数的等待时间,并使得原本需要等待的时间段可以用于处理其他业务逻辑。

Future模式有点类似于商品订单。在网上购物时,提交订单后,在收货的这段时间里无需一直在家里等候,可以先干别的事情。类推到程序设计中时,当提交请求时,期望得到答复时,如果这个答复可能很慢。传统的是一直持续等待直到这个答复收到之后再去做别的事情,但如果利用Future模式,其调用方式改为异步,而原先等待返回的时间段,在主调用函数中,则可以用于处理其他事务。

总结:就是一个请求需要很长时间, 在这个时间里面不是一直等他的结果,而是去做其他的事情。等那边很慢的请求已经有数据了, 回调给现在的客户端。

Data

public interface Data {
    String getResult() throws InterruptedException;
}

FutureData

public class FutureData implements Data {
    RealData realData = null; // FutureData是RealData的封装
    boolean isReady = false; // 是否已经准备好
    private FutureTaskCallBack callback;

    public synchronized void setRealData(RealData realData) {
        if (isReady)
            return;
        this.realData = realData;
        isReady = true;
        notifyAll(); // RealData已经被注入到FutureData中了,通知getResult()方法
    }

    @Override
    public synchronized String getResult() throws InterruptedException {
        if (!isReady) {
            wait(); // 一直等到RealData注入到FutureData中
        }
        return realData.getResult();
    }

    public  synchronized String getCallBackResult() throws InterruptedException {
        if (!isReady) {
            wait(); // 一直等到RealData注入到FutureData中
        }
        return callback.messageCallback(this.realData);
    }

    /**
     * @param callback the callback to set
     */
    public void setCallback(FutureTaskCallBack callback) {
        this.callback = callback;
    }


}

RealData

public class RealData implements Data {
    protected String data;
  
    public RealData handleBusiness(String data){
        try {
            System.out.println(Thread.currentThread().getName()+" 长时间业务处理中.......");
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.data = data;
        return this;
    }


    @Override
    public String getResult() throws InterruptedException {
        return data;
    }
}

FutureTaskCallBack

public interface FutureTaskCallBack {
    
    String messageCallback(RealData realData);

}

Client

public class Client {
    public Data request(final String string) {
        final FutureData futureData = new FutureData();

        new Thread(new Runnable() {
            @Override
            public void run() {
                // RealData的构建很慢,所以放在单独的线程中运行
                RealData realData = new RealData();
                realData.handleBusiness(string);
                futureData.setRealData(realData);
            }
        }).start();
        return futureData; // 先直接返回FutureData
    }
}

Main

public class Main {
    public static void main(final String[] args) {
        final Client client = new Client();
        // 这里会立即返回,因为获取的是FutureData,而非RealData
        final Data data = client.request("name=maizi");
        final FutureData future = (FutureData) data;
        future.setCallback(new FutureTaskCallBack() {
            @Override
            public String messageCallback(final RealData realData) {
                System.out.println("回调数据--->" + realData.data);
                return realData.data;
            }

        });
        System.out.println("请求完毕");
        // 使用真实数据
        try {
            // System.out.println("数据=" + data.getResult());

            // 回调
            future.getCallBackResult();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

运行结果

请求完毕
Thread-0 长时间业务处理中.......
回调数据--->name=maizi

jdk自带FutureTask示例

FutureTask的实现

FutureTask是一个基于AQS同步队列实现的一个自定义同步组件,通过对同步状态state的竞争实现acquire或者release操作。

「真诚赞赏,手留余香」

真诚赞赏,手留余香

使用微信扫描二维码完成支付