Future模式

概述:

image.png

Future模式其實(shí)就是1.生產(chǎn)者提交任務(wù)歇攻,不阻塞接著執(zhí)行后續(xù)代碼 2.任務(wù)處理程序接收到任務(wù)后偷偷的自己開線程去異步處理業(yè)務(wù)邏輯(通過循環(huán)等待丁寄、完成通知方式)
關(guān)鍵技術(shù)點(diǎn):
1.Data接口锯玛,F(xiàn)utureData,RealData,Client
2.FutureData while+ready+synchronized+wait+notify
3.Client偷偷的開線程提交異步任務(wù)

使用:
1.自定義方式
2.JDK自帶
新建異步任務(wù)FutureTask(impl Callable<String> ) 暗挑,impl實(shí)現(xiàn)Callable接口的call方法處理邏輯;創(chuàng)建線程池币喧,提交異步任務(wù)琼富;異步任務(wù)完成可以做回調(diào)通知

說到多線程的future,百度 多線程 future,網(wǎng)上也有各式各樣的例子,寫的比我還要好,但是實(shí)在是這個(gè)模式或者說例子以及實(shí)用性太大了,我不得不拿出來講,甚至在實(shí)際生產(chǎn)環(huán)境中也是可以用的.我呢,也是拿出網(wǎng)上的例子詳細(xì)的講一遍~~

看下面的圖↓↓↓↓↓

image.png

如上圖,傳統(tǒng)的訂單下單流程,首先減商品庫存,然后生成訂單,然后生成訂單詳情,再通知短信等等,全部邏輯程序都是串行執(zhí)行的.假如我們的系統(tǒng)特別'困難',減商品庫存要1秒,生成訂單要1秒,生成詳情也要1秒,發(fā)送短信有可能要5秒,這里還不算查詢商品的庫存夠不夠下單等等,那么一系列的操作就要花很多時(shí)間.

那么引入多線程的future有什么好處呢?看下圖↓↓↓↓↓↓↓

image.png

看這圖很簡單,用戶下單,future對(duì)象直接告訴你下單成功,返回給你一個(gè)假數(shù)據(jù),同時(shí)自己偷偷的新建了一個(gè)或者幾個(gè)線程處理其他業(yè)務(wù)邏輯,等邏輯處理完了,再返回一個(gè)正確的結(jié)果.

然后是上代碼~~

public interface Data {
    String getRequest();
}

public class RealData implements Data {
    private String result;

    public RealData(String request) {
        System.out.println("根據(jù)" + request + "進(jìn)行查詢..,要花很久時(shí)間");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("操作完畢,獲取結(jié)果");
        result = "查詢結(jié)果";
    }

    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("請(qǐng)求發(fā)送成功...");
        System.out.println("干其他的事情...");

        String result = data.getRequest();

        System.out.println(result);
    }
}

一共5個(gè)類,剛開始看會(huì)有點(diǎn)懵逼,正常,我也是懵逼的,我到現(xiàn)在也還是懂了90%,為什么懂90%就敢講,其實(shí)也差不多了~自己按照代碼一個(gè)單詞一個(gè)單詞的教,自然就懂思想.就按照我貼的代碼順序我們一點(diǎn)一點(diǎn)看,這個(gè)模式很有意思的,真的能學(xué)到很多東西.

首先看這個(gè)接口Data,只有一個(gè)方法getRequest(),返回String字符串.

然后再看RealData這個(gè)類,實(shí)現(xiàn)了Data接口,首先他有構(gòu)造函數(shù),打印了兩句話,然后中間sleep一下,做這個(gè)sleep我們可以想象成在處理業(yè)務(wù)邏輯.

接著再看FutureData這個(gè)類,也實(shí)現(xiàn)了Data接口.先看FutureData的getRequest()方法,這個(gè)方法先死循環(huán)判斷boolean,如果isReady是true,就阻塞著,不然就返回RealData真的getRequest()方法(真實(shí)的結(jié)果).然后再看setRealData(),判斷isReady,如果是ture,直接return,如果不是就賦值RealData,并修改isReady,然后notify()..

其實(shí)很好理解,不要看到synchronized,notify,wait就暈了,FutureData這個(gè)類干了啥,你想,wait什么?不就是等notify嗎,如果沒有notify,那我就得等著,等什么?還是等通知啊,只有通知了,那么我才能進(jìn)行下去,進(jìn)行下去什么?--->RealData.getRequset()啊,就是真實(shí)的數(shù)據(jù),為什么要等?因?yàn)檫€在處理啊,只有真實(shí)的數(shù)據(jù)處理完了,然后通知,也就是說FutureData這個(gè)類的setRealData()只是起到通知的作用,再看setRealData()傳入的是RealData對(duì)象,RealData干了啥事,不就是有個(gè)構(gòu)造函數(shù)實(shí)現(xiàn)自己的業(yè)務(wù)嗎,實(shí)現(xiàn)完了就可以通知!!還不懂,自己敲代碼..結(jié)合我說的多讀幾遍,別被饒暈了~~~

最后看FutureClient 這個(gè)類,最簡單了,返回futureData,偷偷開了線程,看到RealData realData = new RealData(request)沒有?就是開始執(zhí)行業(yè)務(wù)了,然后當(dāng)FutureData這個(gè)類的setRealData(RealData realData)時(shí)就通知了..我現(xiàn)在都100%懂了~~~~~~~

最后Main方法就不說了~

打印結(jié)果↓↓↓↓↓↓

請(qǐng)求發(fā)送成功...
干其他的事情...
根據(jù)hello,world進(jìn)行查詢..,要花很久時(shí)間
操作完畢,獲取結(jié)果
查詢結(jié)果

第四句話和第五話是2秒后才出來的~~~~

上面的原理你可以不用懂,當(dāng)然懂最好了,可以在面試官面前吹牛逼啊..future模式這么兇殘,jdk也有實(shí)現(xiàn)的,在java.util.concurrent,又是concurrent,這個(gè)工具類真的是強(qiáng)大上代碼,就不說了~

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來表示任務(wù)處理
        Thread.sleep(2000);

        return "這是處理"+Data+"結(jié)果";
    }
}

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);

        // 表示正在處理其他邏輯,或者業(yè)務(wù)
        Thread.sleep(1000);

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

        Long end = System.currentTimeMillis();

        Long useTime = end - start;

        System.out.println("程序運(yùn)行了-->" + useTime + "毫秒");
    }

}

最后奉上打印結(jié)果↓↓↓↓↓

最后結(jié)果-->這是處理hello,world結(jié)果
程序運(yùn)行了-->2004毫秒

看2秒就執(zhí)行完了..最好自己敲一遍~~~~~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市啊送,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌欣孤,老刑警劉巖馋没,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異导街,居然都是意外死亡披泪,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門搬瑰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來款票,“玉大人,你說我怎么就攤上這事泽论“伲” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵翼悴,是天一觀的道長缚够。 經(jīng)常有香客問我,道長鹦赎,這世上最難降的妖魔是什么谍椅? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮古话,結(jié)果婚禮上雏吭,老公的妹妹穿的比我還像新娘。我一直安慰自己陪踩,他們只是感情好杖们,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著肩狂,像睡著了一般摘完。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上傻谁,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天孝治,我揣著相機(jī)與錄音,去河邊找鬼审磁。 笑死荆秦,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的力图。 我是一名探鬼主播步绸,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼吃媒!你這毒婦竟也來了瓤介?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤赘那,失蹤者是張志新(化名)和其女友劉穎刑桑,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體募舟,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡祠斧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拱礁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片琢锋。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡辕漂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吴超,到底是詐尸還是另有隱情钉嘹,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布鲸阻,位于F島的核電站跋涣,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏鸟悴。R本人自食惡果不足惜陈辱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望细诸。 院中可真熱鬧沛贪,春花似錦、人聲如沸揍堰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽屏歹。三九已至隐砸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蝙眶,已是汗流浹背季希。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留幽纷,地道東北人式塌。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像友浸,于是被迫代替她去往敵國和親峰尝。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容