多线程设计模式-Future模式

Future模式就拿对商品下订单这个操作来说,用户线程A提交订单后,这条用户线程A可以先去干其他的事情,然后再去创建一条B线程去帮这用户创建订单。如果在B线程还没有创建出来订单的时候,用户线程A去调用订单信息,此时线程A会阻塞等待线程B创建出来订单在获取订单信息,否则会直接把线程B创建出来的订单信息返回。再举个实用的栗子:Ajax的异步请求其实很类似Future模式。页面是异步的进行后台处理,用户无须一直等待请求的结果,可以继续浏览或 操作其他内容。

现在代码实现一个Future模式,先看图:

 获取数据接口:Data

public interface Data {

    // 获取数据的方法
    String getRequest();

}

 客户端:FutureClient

public class FutureClient {

    //发起请求
    public Data request(String param){
        //1、将包装类先返回给发起请求的客户,告诉他请求已经接收到了,可以去干其他事情了。(其实此时返回给客户端的是一个空对象)
        FutureData futureData = new FutureData();
        //2、开启一个线程,去查询真实的数据,
        new Thread(() -> {
            RealData realData = new RealData(param);
            futureData.setRequest(realData);
        }).start();
        //3、快速返回
        return futureData;
    }
}

数据包装类:FutureData


/**
 * 数据包装类
 */
public class FutureData implements Data {

    private RealData realData;
    private boolean isRealData = false;
    //判断是否装载好了数据
    //这里需要线程同步(同一时间只能有一个线程操作getRequest(),setRequest(RealData realData)方法)
    @Override
    public synchronized String getRequest() {
        //判断数据是否装载好,如果没有就一直等待下去,
        while (!isRealData){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //返回装载好的真实数据
        return this.realData.getRequest();
    }

    public synchronized void setRequest(RealData realData) {
        if(isRealData)
            return;
        this.realData = realData;
        isRealData = true;
        //唤醒获取数据的线程
        notify();
    }
}

 setRequest(RealData realData),getRequest()方法需要实现线程同步效果,因为有对isRealData属性进行修改,和读取。

 真实数据处理类:RealData

/**
 * 真实的数据查询类
 */
public class RealData implements Data {
    private String result;

    //具体查询业务
    public RealData(String param) {
        System.out.println("根据"+param+"进行查询,这是一个很耗时的操作");
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("查询完毕!");
        this.result = "zhangsan";
    }

    @Override
    public String getRequest() {
        return this.result;
    }
}

main:

public class Main {
    public static void main(String[] args) {
        //初始化客户端
        FutureClient  client = new FutureClient();
        //发送请求后,立即返回一个结果(没有进行查询)
        Data zhangsan = client.request("张三");

        //如果没有使用Future模式,此时是处于阻塞状态,需要等待数据查询出来返回结果
        System.out.println("发送请求成功!!");

        //使用了Future模式就可以干其他事了,(让FutureClient创建的哪个线程去查询)
        System.out.println("去干其他事");

        //等业务需要其结果的时候,调用getRequest()方法,如果此时那个FutureClient创建的线程查询出来数据,就直接返回,否则阻塞等他查询出来
        System.out.println("结果:"+zhangsan.getRequest());

    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值