Java的Future模式

Future:未来。个人理解Future模式类似于回调函数,提前返回一个空壳结果,当需要用到这个结果时,再从空壳结果中取得已经计算完成的真实结果。

举个例子:执行某一个功能之后,开启一个新的线程去执行需要计算的返回数据(假设耗时1秒),并且立即返回数据A(这是,数据里没有内容),然后执行后续代码(假设耗时500毫秒)。当后续代码执行到需要用到A时(假设耗时200毫秒),再从数据A中取得数据,这时主线程阻塞在此等待300毫秒,当数据准备完毕调用notify通知主线程,即可得到A的返回数据,继续执行后续操作(总耗时:1秒)。如果不用Future模式串行操作,那么一共耗时1.5秒(1秒计算A,500毫秒执行后续代码)。

Future模式中需要有几个角色

1. 空壳结果(FutureData)

2. 真实结果(RealData),存放结果

3. 空壳与真实结果的实现接口(Data)

4. 未来客户端(用户整合空壳与真实结果,FutureClient)

Data需要提供一个协议,用于取得结果result,FutureData与RealData都实现该协议

package thread_demo_01;

/**
 * @Author: yesiming
 * @Platform: Mac
 * @Date: 3:39 PM 2019/10/10
 */
public interface M_Data {
    String getQueryResult();
}

FutueData还需要提供一个设置真实数据的方法,用于真实数据准备完毕后放入到空壳数据中

package thread_demo_01;

/**
 * @Author: yesiming
 * @Platform: Mac
 * @Date: 3:39 PM 2019/10/10
 */
public class M_FutureData implements M_Data {

    private M_RealData realData;

    private boolean isReady = false;

    @Override
    public synchronized String getQueryResult() {
        while(!isReady) {
            try {
                wait(); // 如果不用wait和nodify,这里就得轮训判断了。
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        return this.realData.getQueryResult();
    }

    public synchronized void setRealData(M_RealData realData) {
        // 如果已经处理完成,直接返回
        if(isReady) {
            return;
        }

        // 如果没有处理完成,就装载真实对象,然后通知getRequest
        this.realData = realData;
        isReady = true;
        notify();
    }
}

先用FutureClient调用空壳数据,未来数据向外提供查询方法query,该方法直接返回新建的未来数据对象,然后新启动一个线程为未来数据对象填充真实数据

package thread_demo_01;

/**
 * @Author: yesiming
 * @Platform: Mac
 * @Date: 3:55 PM 2019/10/10
 */
public class M_FutureClient {

    public M_Data query(final String queryStr) {
        // 1. 让代理对象先返回给客户端,告诉他们请求已经收到,主线程可以做后续处理了。。。
        final M_FutureData futureData = new M_FutureData();

        // 2. 启动一个新线程,去家在真实数据,然后传递给代理对象
        new Thread(() -> {
            M_RealData realData = new M_RealData(queryStr);
            futureData.setRealData(realData);
        }).start();

        return futureData;
    }
}

下面是真实结果,这里做耗时的数据处理操作

package thread_demo_01;

/**
 * @Author: yesiming
 * @Platform: Mac
 * @Date: 3:44 PM 2019/10/10
 */
public class M_RealData implements M_Data {

    private String result;

    /**
     * 这里做数据的处理封装,耗时操作
     * @param queryStr
     */
    public M_RealData(String queryStr) {
        System.out.println("开始根据queryStr处理数据,这个过程可能会比较耗时");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("数据处理完成,赋值result");
        result = "处理完成的数据";
    }

    @Override
    public String getQueryResult() {
        return result;
    }
}

下面外部调用未来客户端

package thread_demo_01;

/**
 * @Author: yesiming
 * @Platform: Mac
 * @Date: 4:32 PM 2019/10/10
 */
public class M_Main {

    public static void main(String[] args) {
        M_FutureClient client = new M_FutureClient();
        M_Data data = client.query("asdfasd");
        System.out.println("这里可以做别的事儿了。。。");
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("返回数据是:" + data.getQueryResult());
    }
}

好,结束

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值