国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

java并發(fā)編程學(xué)習(xí)16--CompletableFuture(三)

馬忠志 / 1726人閱讀

摘要:所以很容易出現(xiàn)某一個(gè)商店的數(shù)據(jù)遲遲無(wú)法返回的情況。工廠方法接受由對(duì)象構(gòu)成的數(shù)組數(shù)組中所有的完成后它返回一個(gè)對(duì)象。異步的可以通過(guò)進(jìn)行合并,無(wú)論他們之間是否有依賴關(guān)系。可以為注冊(cè)一個(gè)回調(diào)函數(shù),在執(zhí)行完畢時(shí)使用。

【最佳價(jià)格查詢器的優(yōu)化

由于我們的兩個(gè)遠(yuǎn)程服務(wù):1.查詢價(jià)格,2.查詢折扣價(jià)格都是基于網(wǎng)絡(luò)的。所以很容易出現(xiàn)某一個(gè)商店的數(shù)據(jù)遲遲無(wú)法返回的情況。由于這些原因,我希望查詢器在查詢時(shí)能夠?qū)⒛玫綌?shù)據(jù)先返回過(guò)來(lái),而不是等待所有的異步查詢完成后集中返回一個(gè)List。
我們首要需要避免的就是:等待創(chuàng)建一個(gè)包含所有價(jià)格的List。我們應(yīng)該直接處理CompletableFuture流,然后去響應(yīng)他的completion事件,每一個(gè)CompletableFuture對(duì)象完成時(shí)獲取到相應(yīng)的返回值。

先將Discount的折扣服務(wù)延遲時(shí)間修改為隨機(jī)值:

    //計(jì)算折扣價(jià)格
    private static Double apply(double price ,Code code){
        //模擬遠(yuǎn)程操作的延遲
        delay();
        return (price * (100 - code.percantage)) / 100;
    }
    private static void delay(){
        try {
            //隨機(jī)延遲時(shí)間
            int delay = 500 + random.nextInt(2000);
            Thread.sleep(delay);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

開(kāi)始實(shí)現(xiàn)最佳價(jià)格查詢器:

package BestPriceFinder;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 最佳價(jià)格查詢器
 */
public class BestFinder {

    List shops = Arrays.asList(
            new Shop("A"),
            new Shop("B"),
            new Shop("C"),
            new Shop("D"),
            new Shop("E"),
            new Shop("F"),
            new Shop("G"),
            new Shop("H"),
            new Shop("I"),
            new Shop("J")
    );

    public void findPricesContinue(String product){
        long st = System.currentTimeMillis();
        Stream> futurePrices = shops.stream()
                //首先異步獲取價(jià)格
                .map(shop -> CompletableFuture.supplyAsync(() -> shop.getPriceFormat(product),myExecutor))
                //將獲取的字符串解析成對(duì)象
                .map(future -> future.thenApply(Quote::parse))
                //使用另一個(gè)異步任務(wù)有獲取折扣價(jià)格
                .map(future -> future.thenCompose(quote -> CompletableFuture.supplyAsync(() -> Discount.applyDiscount(quote),myExecutor)));
        //thenAccept()會(huì)在CompletableFuture完成之后使用他的返回值,這里會(huì)持續(xù)執(zhí)行子線程
        CompletableFuture[] futures = futurePrices.map(f -> f.thenAccept(s -> {
                                                                            String sout = String.format("%s done in %s mesc",s,(System.currentTimeMillis() - st));
                                                                            System.out.println(sout);
                                                                         }))
                                                  .toArray(size -> new CompletableFuture[size]);
        //allOf()工廠方法接受由CompletableFuture對(duì)象構(gòu)成的數(shù)組,這里使用其等待所有的子線程執(zhí)行完畢
        CompletableFuture.allOf(futures).join();
    }

  

    /**
     * 異步查詢
     * 相比并行流的話CompletableFuture更有優(yōu)勢(shì):可以對(duì)執(zhí)行器配置,設(shè)置線程池大小
     */
    @SuppressWarnings("all")
    private final Executor myExecutor = Executors.newFixedThreadPool(Math.min(shops.size(), 100), new ThreadFactory() {
        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r);
            //使用守護(hù)線程保證不會(huì)阻止程序的關(guān)停
            t.setDaemon(true);
            return t;
        }
    });
   

thenAccept():提供了在CompletableFuture對(duì)象完成后使用他的返回值的功能。這樣我們的每一個(gè)CompletableFuture完成后就會(huì)打印他的返回值,最終等待所有的子線程完畢。

allOf():工廠方法接受由CompletableFuture對(duì)象構(gòu)成的數(shù)組,數(shù)組中所有的CompletableFuture完成后它返回一個(gè)CompletableFuture對(duì)象。

anyOf():廠方法接受由CompletableFuture對(duì)象構(gòu)成的數(shù)組,返回?cái)?shù)組中第一個(gè)完成的CompletableFuture的返回值CompletableFuture對(duì)象。

【小結(jié)

執(zhí)行耗時(shí)的操作,尤其是依賴了遠(yuǎn)程服務(wù)的操作,應(yīng)該使用異步任務(wù)提高效率。

盡可能的提供異步API,使用CompletableFuture類提供的特性可以輕松實(shí)現(xiàn)。

CompletableFuture類提供了異常機(jī)制,可以管理與拋出異步任務(wù)中執(zhí)行的異常。

同步的API封裝到CompletableFuture中可以以異步方式使用其結(jié)果。

異步的API可以通過(guò)CompletableFuture進(jìn)行合并,無(wú)論他們之間是否有依賴關(guān)系。

可以為CompletableFuture注冊(cè)一個(gè)回調(diào)函數(shù),在執(zhí)行完畢時(shí)使用。

可以決定什么時(shí)候結(jié)束運(yùn)行,是所有的CompletableFuture結(jié)束后,還是第一個(gè)CompletableFuture結(jié)束時(shí)就完成。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/68258.html

相關(guān)文章

  • <java并發(fā)編程實(shí)戰(zhàn)>學(xué)習(xí)

    摘要:線程封閉當(dāng)訪問(wèn)共享的可變數(shù)據(jù)時(shí),通常需要使用同步。如果僅在單線程內(nèi)訪問(wèn)數(shù)據(jù),就不要同步。這種技術(shù)成為線程封閉。棧封閉棧封閉是線程封閉的一種特例,在棧封閉中,只能通過(guò)局部變量才能訪問(wèn)對(duì)象。,對(duì)象是正確創(chuàng)建的。 線程封閉 當(dāng)訪問(wèn)共享的可變數(shù)據(jù)時(shí),通常需要使用同步。一種避免使用同步的方式就是不共享數(shù)據(jù)。如果僅在單線程內(nèi)訪問(wèn)數(shù)據(jù),就不要同步。這種技術(shù)成為線程封閉(Thread Confine...

    Richard_Gao 評(píng)論0 收藏0
  • 從小白程序員一路晉升為大廠高級(jí)技術(shù)專家我看過(guò)哪些書(shū)籍?(建議收藏)

    摘要:大家好,我是冰河有句話叫做投資啥都不如投資自己的回報(bào)率高。馬上就十一國(guó)慶假期了,給小伙伴們分享下,從小白程序員到大廠高級(jí)技術(shù)專家我看過(guò)哪些技術(shù)類書(shū)籍。 大家好,我是...

    sf_wangchong 評(píng)論0 收藏0
  • Java多線程學(xué)習(xí))volatile關(guān)鍵字

    摘要:三關(guān)鍵字能保證原子性嗎并發(fā)編程藝術(shù)這本書(shū)上說(shuō)保證但是在自增操作非原子操作上不保證,多線程編程核心藝術(shù)這本書(shū)說(shuō)不保證。多線程訪問(wèn)關(guān)鍵字不會(huì)發(fā)生阻塞,而關(guān)鍵字可能會(huì)發(fā)生阻塞關(guān)鍵字能保證數(shù)據(jù)的可見(jiàn)性,但不能保證數(shù)據(jù)的原子性。 系列文章傳送門(mén): Java多線程學(xué)習(xí)(一)Java多線程入門(mén) Java多線程學(xué)習(xí)(二)synchronized關(guān)鍵字(1) java多線程學(xué)習(xí)(二)synchroniz...

    tain335 評(píng)論0 收藏0
  • Java多線程學(xué)習(xí)(七)并發(fā)編程中一些問(wèn)題

    摘要:相比與其他操作系統(tǒng)包括其他類系統(tǒng)有很多的優(yōu)點(diǎn),其中有一項(xiàng)就是,其上下文切換和模式切換的時(shí)間消耗非常少。因?yàn)槎嗑€程競(jìng)爭(zhēng)鎖時(shí)會(huì)引起上下文切換。減少線程的使用。很多編程語(yǔ)言中都有協(xié)程。所以如何避免死鎖的產(chǎn)生,在我們使用并發(fā)編程時(shí)至關(guān)重要。 系列文章傳送門(mén): Java多線程學(xué)習(xí)(一)Java多線程入門(mén) Java多線程學(xué)習(xí)(二)synchronized關(guān)鍵字(1) java多線程學(xué)習(xí)(二)syn...

    dingding199389 評(píng)論0 收藏0
  • Java多線程學(xué)習(xí)(七)并發(fā)編程中一些問(wèn)題

    摘要:因?yàn)槎嗑€程競(jìng)爭(zhēng)鎖時(shí)會(huì)引起上下文切換。減少線程的使用。舉個(gè)例子如果說(shuō)服務(wù)器的帶寬只有,某個(gè)資源的下載速度是,系統(tǒng)啟動(dòng)個(gè)線程下載該資源并不會(huì)導(dǎo)致下載速度編程,所以在并發(fā)編程時(shí),需要考慮這些資源的限制。 最近私下做一項(xiàng)目,一bug幾日未解決,總惶恐。一日頓悟,bug不可怕,怕的是項(xiàng)目不存在bug,與其懼怕,何不與其剛正面。 系列文章傳送門(mén): Java多線程學(xué)習(xí)(一)Java多線程入門(mén) Jav...

    yimo 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<