Future三重奏第一章:Future设计模式及代码示例

Future系列文章

Future三重奏第一章:Future设计模式及代码示例
Future三重奏第二章:FutureTask源码解析
Future三重奏第三章:FutureTask中一些知识点的总结与补充

Future模式的作用

去除等待主函数执行某项耗时操作的等待时间,在执行主函数耗时业务操作的时候,及时返回一个数据,继续主函数剩下的业务,当需要获取之前耗时操作的结果的时候在进行获取

其本质则是在维持主业务顺利进行的同时,异步的执行主业务中的耗时分业务,使得原本需要进行等待的时间可以处理其他的业务

实际业务场景:

在开具电子发票的业务中,当我们申请开电子发票的时候,电子发票并不会立即开票成功,而是需要调取第三方接口,第三方接口在返回告诉我们是否开具成功,这时候需要等待一段时间才能得到开票结果,在等待第三方返回结果的同时,这个时候我们还有其他别的业务要进行处理返回,不可能一直等待第三方返回的数据,这时候我们就可以采用future模式,将该方法改为异步处理,在等待数据返回的时候进行其他业务的处理

future模式核心类作用

此处通过几个简单的类来展示future模式的思路和运行方式
Main类:系统启动类,调用Client类发出业务请求
Client类:该类在接收到构造并返回FutureData类,返回的FutureData类是一个虚假的对象,或者说并不是一个拥有实际数据的对象,Client的核心在于构建一个新的线程去执行RealData类,该类是处理耗时的业务类
Data:获取实际数据的接口,futureData类和realData类需要实现该接口
FutureData类:及时返回调用类,内部封装了实际数据,可通过该类获取实际的业务数据
RealData:实际的业务处理类,耗时较长

future模式示例代码

Main类

发起请求,构建执行了Client类,返回了Data对象,并在最后调用了data对象实际获取到的数据

public class Main {

    public static void main(String args[]){
        Client client=new Client();

        //调用client发送请求
        Data data=client.request("Hello Future!");

        System.out.println("请求完毕!");

        try {
            //模拟处理其他业务
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //调用实际返回的数据
        System.out.println("真实数据:" + data.getResult());

    }
}

Data接口

Main类中实际返回Data对象,该接口提供获取数据的方法

public interface Data {

    String getResult();
}

Client类

在主类中构建的Client类,并返回futureData对象,另一方面通过该类生成线程发出异步请求,新线程中执行业务类,并返回计算结果,将计算结果封装进futureData对象中

public class Client {

    public Data request(String param){

        //立即返回futureData
        FutureData futureData=new FutureData();

        //需要启动一个新线程
        //开启ClientThread线程装配realData
        new Thread(() -> {
            //装配realData
            //RealData为业务类,传递相关参数过去
            RealData realData=new RealData(param);

            //获取到数据后将数据封装进实体类中
            futureData.setRealData(realData);

        }).start();
        return futureData;
    }
}

RealData类

实际业务类,该类主要是执行业务方法并得到计算结果,并提供获取数据的方法

public class RealData implements Data{

    private String result;//封装实际数据


    /**
     * 获取计算结果方法
     * @return
     */
    @Override
    public String getResult() {
        return result;
    }

    public RealData(String param){
        StringBuffer sb=new StringBuffer();

        sb.append(param);

        //模拟业务执行
        //此处通过线程睡眠的方式
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //获取真实数据result,等待再次获取数据
        result=sb.toString();
    }

}

FutureData类

在client的调用中,会首先返回一个空的futuredata对象,然后启动一个新的线程去执行业务类获取数据,在获取数据后,会将获取的数据封装进futuredata类中,所以,futuredata类相应的提供了封装实际数据的方法。当你需要获取实际数据当时候,如果尚未获取数据成功,则进入等待队列

public class FutureData implements Data {


    private RealData realData;

    private boolean isReady=false;//如果已经获取数据此处为true

    private ReentrantLock lock=new ReentrantLock();
    private Condition condition=lock.newCondition();

    /**
     * 获取实际数据
     * @return
     */
    @Override
    public String getResult()
    {
        //如果尚未成功获取数据,则当前线程加入等待队列
        while (!isReady){
            try {
                lock.lock();
                condition.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
        }
        return realData.getResult();
    }

    public void setRealData(RealData realData){
        lock.lock();
        if (isReady){
            return;
        }

        //装载实际数据对象
        this.realData = realData;
        isReady = true;
        condition.signal();
        lock.unlock();
    }
}

以上就是future设计模式的简单实现,future模式在线程池的实现中有很大的体现,在第二章中我会详细介绍jdk中futuretask的详细实现,在线程池模块中也会对futureTask的使用作出详细介绍

  • 如果喜欢我的文章,可以随手点一下文末的喜欢
  • 技术理解不到或有错误请直(bu)接(yao)指(ma)出(wo)
  • 写作不易!
尤文图斯-迪巴拉
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容