java中Future的使用

java中Future的使用

Future是java 1.5引入的一個(gè)interface酗昼,可以方便的用于異步結(jié)果的獲取。 本文將會(huì)通過(guò)具體的例子講解如何使用Future梳猪。

創(chuàng)建Future

正如上面所說(shuō)麻削,F(xiàn)uture代表的是異步執(zhí)行的結(jié)果,意思是當(dāng)異步執(zhí)行結(jié)束之后春弥,返回的結(jié)果將會(huì)保存在Future中呛哟。

那么我們什么時(shí)候會(huì)用到Future呢? 一般來(lái)說(shuō)匿沛,當(dāng)我們執(zhí)行一個(gè)長(zhǎng)時(shí)間運(yùn)行的任務(wù)時(shí)扫责,使用Future就可以讓我們暫時(shí)去處理其他的任務(wù),等長(zhǎng)任務(wù)執(zhí)行完畢再返回其結(jié)果逃呼。

經(jīng)常會(huì)使用到Future的場(chǎng)景有:1. 計(jì)算密集場(chǎng)景鳖孤。2. 處理大數(shù)據(jù)量。3. 遠(yuǎn)程方法調(diào)用等抡笼。

接下來(lái)我們將會(huì)使用ExecutorService來(lái)創(chuàng)建一個(gè)Future苏揣。

    <T> Future<T> submit(Callable<T> task);

上面是ExecutorService中定義的一個(gè)submit方法,它接收一個(gè)Callable參數(shù)蔫缸,并返回一個(gè)Future腿准。

我們用一個(gè)線程來(lái)計(jì)算一個(gè)平方運(yùn)算:

    private ExecutorService executor
            = Executors.newSingleThreadExecutor();

    public Future<Integer> calculate(Integer input) {
        return executor.submit(() -> {
            System.out.println("Calculating..."+ input);
            Thread.sleep(1000);
            return input * input;
        });
    }

submit需要接受一個(gè)Callable參數(shù),Callable需要實(shí)現(xiàn)一個(gè)call方法,并返回結(jié)果吐葱。這里我們使用lamaba表達(dá)式來(lái)簡(jiǎn)化這一個(gè)流程街望。

從Future獲取結(jié)果

上面我們創(chuàng)建好了Future,接下來(lái)我們看一下怎么獲取到Future的值弟跑。

       FutureUsage futureUsage=new FutureUsage();
        Future<Integer> futureOne = futureUsage.calculate(20);
        while(!futureOne.isDone()) {
            System.out.println("Calculating...");
            Thread.sleep(300);
        }
        Integer result = futureOne.get();

首先我們通過(guò)Future.isDone() 來(lái)判斷這個(gè)異步操作是否執(zhí)行完畢灾前,如果完畢我們就可以直接調(diào)用futureOne.get()來(lái)獲得Futre的結(jié)果。

這里futureOne.get()是一個(gè)阻塞操作孟辑,會(huì)一直等待異步執(zhí)行完畢才返回結(jié)果哎甲。

如果我們不想等待,future提供了一個(gè)帶時(shí)間的方法:

Integer result = futureOne.get(500, TimeUnit.MILLISECONDS);

如果在等待時(shí)間結(jié)束的時(shí)候饲嗽,F(xiàn)uture還有返回炭玫,則會(huì)拋出一個(gè)TimeoutException。

取消Future

如果我們提交了一個(gè)異步程序貌虾,但是想取消它吞加, 則可以這樣:

uture<Integer> futureTwo = futureUsage.calculate(4);

        boolean canceled = futureTwo.cancel(true);

Future.cancel(boolean) 傳入一個(gè)boolean參數(shù),來(lái)選擇是否中斷正在運(yùn)行的task尽狠。

如果我們cancel之后衔憨,再次調(diào)用get()方法,則會(huì)拋出CancellationException袄膏。

多線程環(huán)境中運(yùn)行

如果有兩個(gè)計(jì)算任務(wù)践图,先看下在單線程下運(yùn)行的結(jié)果。

        Future<Integer> future1 = futureUsage.calculate(10);
        Future<Integer> future2 = futureUsage.calculate(100);

        while (!(future1.isDone() && future2.isDone())) {
            System.out.println(
                    String.format(
                            "future1 is %s and future2 is %s",
                            future1.isDone() ? "done" : "not done",
                            future2.isDone() ? "done" : "not done"
                    )
            );
            Thread.sleep(300);
        }

        Integer result1 = future1.get();
        Integer result2 = future2.get();

        System.out.println(result1 + " and " + result2);

因?yàn)槲覀兺ㄟ^(guò)Executors.newSingleThreadExecutor()來(lái)創(chuàng)建的單線程池沉馆。所以運(yùn)行結(jié)果如下:

Calculating...10
future1 is not done and future2 is not done
future1 is not done and future2 is not done
future1 is not done and future2 is not done
future1 is not done and future2 is not done
Calculating...100
future1 is done and future2 is not done
future1 is done and future2 is not done
future1 is done and future2 is not done
100 and 10000

如果我們使用Executors.newFixedThreadPool(2)來(lái)創(chuàng)建一個(gè)多線程池码党,則可以得到如下的結(jié)果:

calculating...10
calculating...100
future1 is not done and future2 is not done
future1 is not done and future2 is not done
future1 is not done and future2 is not done
future1 is not done and future2 is not done
100 and 10000

本文的例子可以參考https://github.com/ddean2009/learn-java-concurrency/tree/master/future

更多教程請(qǐng)參考 flydean的博客

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市悍及,隨后出現(xiàn)的幾起案子闽瓢,更是在濱河造成了極大的恐慌,老刑警劉巖心赶,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扣讼,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡缨叫,警方通過(guò)查閱死者的電腦和手機(jī)椭符,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)耻姥,“玉大人销钝,你說(shuō)我怎么就攤上這事∷龃兀” “怎么了蒸健?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵座享,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我似忧,道長(zhǎng)渣叛,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任盯捌,我火速辦了婚禮淳衙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘饺著。我一直安慰自己箫攀,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布幼衰。 她就那樣靜靜地躺著靴跛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪渡嚣。 梳的紋絲不亂的頭發(fā)上汤求,一...
    開(kāi)封第一講書(shū)人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音严拒,去河邊找鬼。 笑死竖独,一個(gè)胖子當(dāng)著我的面吹牛裤唠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播莹痢,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼种蘸,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了竞膳?” 一聲冷哼從身側(cè)響起航瞭,我...
    開(kāi)封第一講書(shū)人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎坦辟,沒(méi)想到半個(gè)月后刊侯,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡锉走,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年滨彻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挪蹭。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡亭饵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出梁厉,到底是詐尸還是另有隱情辜羊,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站八秃,受9級(jí)特大地震影響碱妆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜喜德,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一山橄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧舍悯,春花似錦航棱、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至秕豫,卻和暖如春朴艰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背混移。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工祠墅, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人歌径。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓毁嗦,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親回铛。 傳聞我的和親對(duì)象是個(gè)殘疾皇子狗准,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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