Future模式

概述:

image.png

Future模式其实就是1.生产者提交任务,不阻塞接着执行后续代码 2.任务处理程序接收到任务后偷偷的自己开线程去异步处理业务逻辑(通过循环等待、完成通知方式)
关键技术点:
1.Data接口,FutureData,RealData,Client
2.FutureData while+ready+synchronized+wait+notify
3.Client偷偷的开线程提交异步任务

使用:
1.自定义方式
2.JDK自带
新建异步任务FutureTask(impl Callable<String> ) ,impl实现Callable接口的call方法处理逻辑;创建线程池,提交异步任务;异步任务完成可以做回调通知

说到多线程的future,百度 多线程 future,网上也有各式各样的例子,写的比我还要好,但是实在是这个模式或者说例子以及实用性太大了,我不得不拿出来讲,甚至在实际生产环境中也是可以用的.我呢,也是拿出网上的例子详细的讲一遍~~

看下面的图↓↓↓↓↓

image.png

如上图,传统的订单下单流程,首先减商品库存,然后生成订单,然后生成订单详情,再通知短信等等,全部逻辑程序都是串行执行的.假如我们的系统特别'困难',减商品库存要1秒,生成订单要1秒,生成详情也要1秒,发送短信有可能要5秒,这里还不算查询商品的库存够不够下单等等,那么一系列的操作就要花很多时间.

那么引入多线程的future有什么好处呢?看下图↓↓↓↓↓↓↓

image.png

看这图很简单,用户下单,future对象直接告诉你下单成功,返回给你一个假数据,同时自己偷偷的新建了一个或者几个线程处理其他业务逻辑,等逻辑处理完了,再返回一个正确的结果.

然后是上代码~~

public interface Data {
    String getRequest();
}

public class RealData implements Data {
    private String result;

    public RealData(String request) {
        System.out.println("根据" + request + "进行查询..,要花很久时间");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("操作完毕,获取结果");
        result = "查询结果";
    }

    public String getRequest() {
        return result;
    }
}

public class FutureData implements Data {

    private RealData realData;

    private boolean isReady = false;

    public synchronized String getRequest() {

        while (!isReady) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return this.realData.getRequest();
    }

    public synchronized void setRealData(RealData realData) {
        if (isReady) {
            return;
        }
        this.realData = realData;
        isReady = true;
        notify();
    }
}

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

        new Thread(new Runnable() {

            public void run() {
                RealData realData = new RealData(request);
                futureData.setRealData(realData);
            }
        }).start();

        return futureData;
    }
}

public class Main {

    public static void main(String[] args) {
        FutureClient fClient = new FutureClient();

        Data data = fClient.request("hello,world");

        System.out.println("请求发送成功...");
        System.out.println("干其他的事情...");

        String result = data.getRequest();

        System.out.println(result);
    }
}

一共5个类,刚开始看会有点懵逼,正常,我也是懵逼的,我到现在也还是懂了90%,为什么懂90%就敢讲,其实也差不多了~自己按照代码一个单词一个单词的教,自然就懂思想.就按照我贴的代码顺序我们一点一点看,这个模式很有意思的,真的能学到很多东西.

首先看这个接口Data,只有一个方法getRequest(),返回String字符串.

然后再看RealData这个类,实现了Data接口,首先他有构造函数,打印了两句话,然后中间sleep一下,做这个sleep我们可以想象成在处理业务逻辑.

接着再看FutureData这个类,也实现了Data接口.先看FutureData的getRequest()方法,这个方法先死循环判断boolean,如果isReady是true,就阻塞着,不然就返回RealData真的getRequest()方法(真实的结果).然后再看setRealData(),判断isReady,如果是ture,直接return,如果不是就赋值RealData,并修改isReady,然后notify()..

其实很好理解,不要看到synchronized,notify,wait就晕了,FutureData这个类干了啥,你想,wait什么?不就是等notify吗,如果没有notify,那我就得等着,等什么?还是等通知啊,只有通知了,那么我才能进行下去,进行下去什么?--->RealData.getRequset()啊,就是真实的数据,为什么要等?因为还在处理啊,只有真实的数据处理完了,然后通知,也就是说FutureData这个类的setRealData()只是起到通知的作用,再看setRealData()传入的是RealData对象,RealData干了啥事,不就是有个构造函数实现自己的业务吗,实现完了就可以通知!!还不懂,自己敲代码..结合我说的多读几遍,别被饶晕了~~~

最后看FutureClient 这个类,最简单了,返回futureData,偷偷开了线程,看到RealData realData = new RealData(request)没有?就是开始执行业务了,然后当FutureData这个类的setRealData(RealData realData)时就通知了..我现在都100%懂了~~~~~~~

最后Main方法就不说了~

打印结果↓↓↓↓↓↓

请求发送成功...
干其他的事情...
根据hello,world进行查询..,要花很久时间
操作完毕,获取结果
查询结果

第四句话和第五话是2秒后才出来的~~~~

上面的原理你可以不用懂,当然懂最好了,可以在面试官面前吹牛逼啊..future模式这么凶残,jdk也有实现的,在java.util.concurrent,又是concurrent,这个工具类真的是强大上代码,就不说了~

import java.util.concurrent.Callable;

public class RealData implements Callable<String> {
    private String Data;

    public RealData(String Data) {
        this.Data = Data;
    }

    public String call() throws Exception {
        //利用sleep来表示任务处理
        Thread.sleep(2000);

        return "这是处理"+Data+"结果";
    }
}

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

public class Main {

    public static void main(String[] args) throws Exception {
        Long start = System.currentTimeMillis();

        FutureTask<String> futureTask = new FutureTask<>(new RealData("hello,world"));
        ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(1);
        newFixedThreadPool.submit(futureTask);

        // 表示正在处理其他逻辑,或者业务
        Thread.sleep(1000);

        System.out.println("最后结果-->" + futureTask.get());

        Long end = System.currentTimeMillis();

        Long useTime = end - start;

        System.out.println("程序运行了-->" + useTime + "毫秒");
    }

}

最后奉上打印结果↓↓↓↓↓

最后结果-->这是处理hello,world结果
程序运行了-->2004毫秒

看2秒就执行完了..最好自己敲一遍~~~~~

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

推荐阅读更多精彩内容