總結(jié)一下guava常用并發(fā)庫的用法

一慨削、ThreadFactoryBuilder

ThreadFactoryBuilder主要用于線程池技術(shù)中兼都。當我們需要給新創(chuàng)建的線程取名字嫂沉、或者設(shè)置為守護線程、錯誤處理器等操作時,線程工廠的好處就提現(xiàn)出來了扮碧。

  1. 不用ThreadFactoryBuilder的時候 我們這么寫代碼趟章。我們每次要新建一個類來實現(xiàn)ThreadFactory,有點繁瑣。
image.png
  1. 用了ThreadFactoryBuilder之后慎王,好處不言而喻蚓土。ThreadFactoryBuilder是一個Builder設(shè)計模式的應(yīng)用,可以設(shè)置守護進程、錯誤處理器赖淤、線程名字蜀漆。
image.png
二、SettableFuture

settableFuture我們可以認為是一種異步轉(zhuǎn)同步的工具咱旱。我們平常只聽說過同步轉(zhuǎn)異步,這次竟然是異步轉(zhuǎn)同步,是不是覺得有點奇怪确丢。先看一下實例:

我們先使用create()創(chuàng)建一個SettableFuture的實例,然后等線程獲取結(jié)果后手動將返回值放入到settableFuture中,類似于一個ThreadLocal.,一切看起來都很自然。但是作用在哪莽龟?個人認為就是get()方法,我們可以設(shè)置超時獲取的時間,如果在指定時間內(nèi)獲取不到,則拋出異常蠕嫁。


image.png
應(yīng)用場景:

我們在做網(wǎng)絡(luò)通信時,假設(shè)一般請求-響應(yīng)都是在3秒以內(nèi)拿到結(jié)果.但有的時候遇到網(wǎng)絡(luò)動蕩、硬件性能問題時會導(dǎo)致超時,5秒,10秒甚至更多毯盈。但是我們希望超過5秒的請求我們就認為失敗,這個時候SettableFuture就可以出場了,代碼優(yōu)雅,又能解決實際問題剃毒。

remoteFuture.get(5,TimeUnit.SECONDS);
三、ListenableFuture

ListenableFuture是基于裝飾器模式實現(xiàn)的:

    ListeningExecutorService listeningExecutor = MoreExecutors.listeningDecorator(executor);
    final ListenableFuture<String> future = listeningExecutor.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                TimeUnit.SECONDS.sleep(2);
                return "hello_world";
            }
        });

我們可以對ExecutorService做一層包裝,返回一個ListenableFuture實例,而ListenableFuture又是集成自Future,擴展了一個addListener監(jiān)聽方法,當任務(wù)執(zhí)行完成,會主動回調(diào)該方法。主要也是彌補了JDK自帶Future的不足,像Netty也優(yōu)雅的實現(xiàn)了異步回調(diào)機制,不需要手動通過Future.get()來獲取結(jié)果赘阀。

        future.addListener(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("收到通知..." + future.get());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            }
        }, listeningExecutor);
四益缠、Futures.addCallback

也是基于異步回調(diào)的機制,個人覺得更加雅觀。

        Futures.addCallback(future, new FutureCallback<String>() {

            @Override
            public void onSuccess(String result) {
            }

            @Override
            public void onFailure(Throwable t) {
                System.out.println("futureException: ");
                t.printStackTrace();
            }
        });
五基公、AsyncFunction

我們調(diào)用ListenableFuture.get方法取回AsyncFunction接口處理后的結(jié)果幅慌。當我們想要異步地執(zhí)行轉(zhuǎn)換邏輯,而不是阻塞的調(diào)用(雖然任務(wù)還沒有完成的時候調(diào)用Future.get方法會阻塞)的時候轰豆,可以使用AsyncFunction接口胰伍。但是AsyncFunction接口并不會異步的執(zhí)行轉(zhuǎn)換邏輯;而只是返回一個Future實例酸休。 看看下面代碼例子:

public class AsyncFuntionSample implements AsyncFunction<Long,String> {
    private ConcurrentMap<Long,String> map = Maps.newConcurrentMap();
    private ListeningExecutorService listeningExecutorService;

    @Override
    public ListenableFuture<String> apply(final Long input) throws Exception {
    if(map.containsKey(input)) {
        SettableFuture<String> listenableFuture = SettableFuture.create();
        listenableFuture.set(map.get(input));
        return listenableFuture;
    }else{
        return listeningExecutorService.submit(new Callable<String>(){
        @Override
        public String call() throws Exception {
            String retrieved = service.get(input);
            map.putIfAbsent (input,retrieved);
            return retrieved;
        }
    });
    }
}

我們這個類實現(xiàn)AsyncFunction接口骂租,并且包含一個ConcurrentHashMap實例。當我們調(diào)用apply方法時斑司,我們會首先查看下map中有沒有這個值渗饮,輸入對象作為key。如果我們在map中找到值宿刮,我們使用SettableFuture類構(gòu)造出Future對象互站,并且設(shè)置為從map中取出的對象。否則僵缺,我們返回提交Callable給ExecutorService放回的Future對象胡桃。同樣也會放置返回的值到map中去。

六谤饭、補充一下

Futures中還有幾個immediate開頭的方法:

//immediateFuture 表示該方法立即返回
ListenableFuture<String> future = Futures.immediateFuture("immediateFuture");

//實現(xiàn)和immediateFuture差不多,提供了兩個checkedGet()方法
future = Futures.immediateCheckedFuture("immediateCheckedFuture");
        
//構(gòu)造一個cancel的future,當調(diào)用get()方法時  立即拋出異常
future = Futures.immediateCancelledFuture();

//調(diào)用get()方法和checkedGet()拋出異常        
future =Futures.immediateFailedCheckedFuture(newNullPointerException("immediateFailedCheckedFuture"));
        
//當調(diào)用get()方法時,拋出異常
future = Futures.immediateFailedFuture(new NullPointerException("immediateFailedFuture"));

這些方法一般結(jié)合著Futures的transform使用:

ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
        ListenableFuture<Integer> futures = executor.submit(new Callable<Integer>() {
            public Integer call() throws Exception {
                Thread.sleep(2000);
                System.out.println("future task done......");
                return 1;
            }
        });
//因為futures.get()返回的是Integer,如果想在get()方法返回之后,利用其返回值做一些其他操作.就可以使用
transform()方法,手動轉(zhuǎn)換為對其類型結(jié)果的獲取:
        ListenableFuture<Boolean> transform = Futures.transformAsync(futures, new AsyncFunction<Integer, Boolean>() {
            public ListenableFuture<Boolean> apply(Integer integer) throws Exception {
                return integer > 0 ? Futures.immediateFuture(Boolean.TRUE) : Futures.immediateFuture(Boolean.FALSE);
            }
        });

使用JdkFutureAdapters來完成JDK Future到ListenableFuture的轉(zhuǎn)換:

  ListenableFuture<Boolean> listenFuture = JdkFutureAdapters.listenInPoolThread(transformFuture);

更多詳情可以參考: https://stonelion.gitbooks.io/guava_ch/content/index.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末标捺,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子揉抵,更是在濱河造成了極大的恐慌亡容,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件冤今,死亡現(xiàn)場離奇詭異闺兢,居然都是意外死亡,警方通過查閱死者的電腦和手機戏罢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門屋谭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人龟糕,你說我怎么就攤上這事桐磁。” “怎么了讲岁?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵我擂,是天一觀的道長衬以。 經(jīng)常有香客問我,道長校摩,這世上最難降的妖魔是什么看峻? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮衙吩,結(jié)果婚禮上互妓,老公的妹妹穿的比我還像新娘。我一直安慰自己坤塞,他們只是感情好冯勉,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著尺锚,像睡著了一般珠闰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瘫辩,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機與錄音坛悉,去河邊找鬼伐厌。 笑死,一個胖子當著我的面吹牛裸影,可吹牛的內(nèi)容都是我干的挣轨。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼轩猩,長吁一口氣:“原來是場噩夢啊……” “哼卷扮!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起均践,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤晤锹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后彤委,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鞭铆,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年焦影,在試婚紗的時候發(fā)現(xiàn)自己被綠了车遂。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡斯辰,死狀恐怖舶担,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情彬呻,我是刑警寧澤衣陶,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布柄瑰,位于F島的核電站,受9級特大地震影響祖搓,放射性物質(zhì)發(fā)生泄漏狱意。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一拯欧、第九天 我趴在偏房一處隱蔽的房頂上張望详囤。 院中可真熱鬧,春花似錦镐作、人聲如沸藏姐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽羔杨。三九已至,卻和暖如春杨蛋,著一層夾襖步出監(jiān)牢的瞬間兜材,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工逞力, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留曙寡,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓寇荧,卻偏偏與公主長得像举庶,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子揩抡,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理户侥,服務(wù)發(fā)現(xiàn),斷路器峦嗤,智...
    卡卡羅2017閱讀 134,601評論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法蕊唐,類相關(guān)的語法,內(nèi)部類的語法寻仗,繼承相關(guān)的語法刃泌,異常的語法,線程的語...
    子非魚_t_閱讀 31,587評論 18 399
  • //Clojure入門教程: Clojure – Functional Programming for the J...
    葡萄喃喃囈語閱讀 3,622評論 0 7
  • 曾有人說過署尤,愛情沒有天荒地老也沒有執(zhí)手一生耙替,有的不過是救贖,有人救贖他人的時間較長曹体,有人救贖他人的時間短如一瞬俗扇。 ...
    槐綾閱讀 423評論 0 1
  • 一個人走在這星空之上 探索星球留下的遠古遺跡 我的眼眸如星空般深邃 除了腳印什么都沒有 我的身邊多了一個人 那是我...
    夏江南愛上夏雨荷閱讀 547評論 0 2