RxJava2實現(xiàn)請求并發(fā)吆鹤,減少請求所消耗的總時間

首先我們創(chuàng)建兩個Observable1 Observable2來模擬網(wǎng)絡(luò)請求,代碼如下:

            //每個子Observable都要加subscribeOn(Schedulers.io())指定為異步線程 不同線程來處理請求達到并發(fā)
            val observable1: Observable<String> = Observable.create(ObservableOnSubscribe<String> {
                Log.e("asd" , "observable1---"+Thread.currentThread().name)
                Thread.sleep(5000)
                it.onNext("1111")
                it.onComplete()
            }).subscribeOn(Schedulers.io())


            val observable2: Observable<String> = Observable.create(ObservableOnSubscribe<String>{
                Log.e("asd" , "observable2---"+Thread.currentThread().name)
                Thread.sleep(10000)
                it.onNext("2222")
                it.onComplete()
            }).subscribeOn(Schedulers.io())

observable1中第一行打印了線程的名字,當(dāng)執(zhí)行到這里的時候代表該請求已經(jīng)在執(zhí)行了洛心,然后讓線程休眠5秒鐘模擬耗時,休眠過后發(fā)送一個111字符串出去調(diào)用onComplete完成本此請求

observable2中類似和observable1類似题篷,只是休眠時間變成10秒词身,10秒過后請求完成發(fā)送數(shù)據(jù),因為兩個請求由于返回數(shù)據(jù)和網(wǎng)絡(luò)狀態(tài)番枚,等等原因法严,他們所消耗的時間肯定不一樣的。

這里需要注意 每個子的Observable必須要單獨指定線程subscribeOn(Schedulers.io())户辫,如果不加這個渐夸,那么兩個請求還是在一個線程中執(zhí)行,必定會有先后渔欢,達不到并發(fā)的效果墓塌,這里后面會展示不并發(fā)的效果

接下來吧請求合并一起使用zip關(guān)鍵字代碼如下:

            val start = System.currentTimeMillis()
            Observable.zip(observable1, observable2,BiFunction<String, String, String> { t1, t2 ->
                    Log.e("asd" , "zip:"+Thread.currentThread().name)
                    //這里是兩個請求都返回了之后 執(zhí)行到這里 把數(shù)據(jù)封裝到一個類中返回,這里只是簡單的吧他們加起來返回了
                    t1 + t2
                }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe {
                    val end = System.currentTimeMillis() - start
                    Log.e("asd" , "請求的數(shù)據(jù):${it}---耗時:${end}---observable:"+Thread.currentThread().name)
                }

看下打印的日志奥额,分析一下

2019-10-25 17:18:39.143 19436-19772/com.joyrun.study E/asd: observable2---RxCachedThreadScheduler-3
2019-10-25 17:18:39.143 19436-19771/com.joyrun.study E/asd: observable1---RxCachedThreadScheduler-2
2019-10-25 17:18:49.144 19436-19772/com.joyrun.study E/asd: zip:RxCachedThreadScheduler-3
2019-10-25 17:18:49.145 19436-19436/com.joyrun.study E/asd: 請求的數(shù)據(jù):11112222---耗時:10004---observable:main

17:18:39 同一時間打印了observable1 observable2苫幢,說明這兩個請求已經(jīng)并發(fā)執(zhí)行了

17:18:49 10秒鐘過后兩個請求都完成了,同一時間把數(shù)據(jù)返回主線程垫挨,打印出請求的數(shù)據(jù):11112222---耗時:10004---observable:main
總共耗時10004 10秒 也就是說兩個請求并發(fā)了韩肝,最后拿到數(shù)據(jù)的消耗時間是倆個請求中最長的耗時時間,如果你想先執(zhí)行完 就先處理的話 使用merge操作符就可以了,最后面展示用法

下面看下 不并發(fā)的情況九榔,也就是每個子Observable不單獨指定線程哀峻,那么他們還是在同一線程中執(zhí)行,打印日志中可以看到哲泊,所以必定是有一個先一個后執(zhí)行的剩蟀,達不到并發(fā)效果

            val observable1: Observable<String> = Observable.create {
                Log.e("asd" , "observable1:"+Thread.currentThread().name)
                Thread.sleep(5000)
                it.onNext("1111")
                it.onComplete()
            }
            val observable2: Observable<String> = Observable.create {
                Log.e("asd" , "observable2:"+Thread.currentThread().name)
                Thread.sleep(10000)
                it.onNext("2222")
                it.onComplete()
            }

解釋:使用Observable.zip將兩個Observable合并成一個指定子線程,然后在BiFunction的接口函數(shù)中就可以拿到這兩個請求返回的數(shù)據(jù)切威,主意執(zhí)行到這里一定是兩個請求都成功返回數(shù)據(jù)了育特,看下打印的日志

2019-10-25 17:03:46.903 11409-11465/com.joyrun.study E/asd: observable1:RxCachedThreadScheduler-1
2019-10-25 17:03:51.905 11409-11465/com.joyrun.study E/asd: observable2:RxCachedThreadScheduler-1
2019-10-25 17:04:01.906 11409-11465/com.joyrun.study E/asd: zip:RxCachedThreadScheduler-1
2019-10-25 17:04:01.907 11409-11409/com.joyrun.study E/asd: 請求的數(shù)據(jù):11112222---耗時:15006---observable:main

17:03:46 開始了第一個請求

17:03:51 五秒過后執(zhí)行了第二個請求

17:04:01 也就是10秒過后第二個請求執(zhí)行完成 就會調(diào)用到BiFunction的接口函數(shù)中做兩個請求數(shù)據(jù)的處理并返回

17:04:01 同一時間將數(shù)據(jù)返回到了主線程

打兩個請求合并之后的請求總時間15006 15秒鐘 一個5秒一個10秒,雖然請求合并了 但是沒有并發(fā) 請求所消耗的時間 還是兩個請求消耗時間的總和

如果說想并發(fā)請求先朦,那個返回數(shù)據(jù) 就處理那個的話就是用merge操作符即可低嗎如下

            Observable.merge(observable1, observable2).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread()).subscribe {
                    Log.e("asd" , "請求的數(shù)據(jù):${it}---observable:"+Thread.currentThread().name)
                }

打印日志

2019-10-25 17:28:48.586 25014-25108/com.joyrun.study E/asd: observable2:RxCachedThreadScheduler-3
2019-10-25 17:28:48.587 25014-25107/com.joyrun.study E/asd: observable1:RxCachedThreadScheduler-2
2019-10-25 17:28:53.589 25014-25014/com.joyrun.study E/asd: 請求的數(shù)據(jù):1111---observable:main
2019-10-25 17:28:58.587 25014-25014/com.joyrun.study E/asd: 請求的數(shù)據(jù):2222---observable:main

通過打印日志看出兩個請求并發(fā)執(zhí)行缰冤,并且在不同線程中

17:28:53 5秒后執(zhí)行完第一個請求拿到返回數(shù)據(jù)進行處理

17:28:58 10秒后執(zhí)行完第二個請求犬缨,拿到返回數(shù)據(jù)進行處理,注意10秒后 是針對兩個請求并發(fā)處理之后的10秒 并不是第一個請求完了 后10秒

測試中完整代碼如下:

            //----------------------------------------------------------
//            val observable1: Observable<String> = Observable.create {
////                Log.e("asd" , "observable1:"+Thread.currentThread().name)
////                Thread.sleep(5000)
////                it.onNext("1111")
////                it.onComplete()
////            }
////            val observable2: Observable<String> = Observable.create {
////                Log.e("asd" , "observable2:"+Thread.currentThread().name)
////                Thread.sleep(10000)
////                it.onNext("2222")
////                it.onComplete()
////            }
            //----------------------------------------------------------


            //**********************************************************
            //每個子Observable都要加subscribeOn(Schedulers.io())指定為異步線程 不同線程來處理請求達到并發(fā)
            val observable1: Observable<String> = Observable.create(ObservableOnSubscribe<String> {
                Log.e("asd" , "observable1:"+Thread.currentThread().name)
                Thread.sleep(5000)
                it.onNext("1111")
                it.onComplete()
            }).subscribeOn(Schedulers.io())


            val observable2: Observable<String> = Observable.create(ObservableOnSubscribe<String>{
                Log.e("asd" , "observable2:"+Thread.currentThread().name)
                Thread.sleep(10000)
                it.onNext("2222")
                it.onComplete()
            }).subscribeOn(Schedulers.io())
            //**********************************************************

            
            
            //zip
//            val start = System.currentTimeMillis()
//            Observable.zip(observable1, observable2,BiFunction<String, String, String> { t1, t2 ->
//                    Log.e("asd" , "zip:"+Thread.currentThread().name)
//                    //這里是兩個請求都返回了之后 執(zhí)行到這里 把數(shù)據(jù)封裝到一個類中返回棉浸,這里只是簡單的吧他們加起來返回了
//                    t1 + t2
//                }).subscribeOn(Schedulers.io())
//                .observeOn(AndroidSchedulers.mainThread())
//                .subscribe {
//                    val end = System.currentTimeMillis() - start
//                    Log.e("asd" , "請求的數(shù)據(jù):${it}---耗時:${end}---observable:"+Thread.currentThread().name)
//                }

            
            //merge
            Observable.merge(observable1, observable2).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread()).subscribe {
                    Log.e("asd" , "請求的數(shù)據(jù):${it}---observable:"+Thread.currentThread().name)
                }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末怀薛,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子涮拗,更是在濱河造成了極大的恐慌乾戏,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件三热,死亡現(xiàn)場離奇詭異,居然都是意外死亡三幻,警方通過查閱死者的電腦和手機就漾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來念搬,“玉大人抑堡,你說我怎么就攤上這事±驶玻” “怎么了首妖?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長爷恳。 經(jīng)常有香客問我有缆,道長,這世上最難降的妖魔是什么温亲? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任棚壁,我火速辦了婚禮,結(jié)果婚禮上栈虚,老公的妹妹穿的比我還像新娘袖外。我一直安慰自己,他們只是感情好魂务,可當(dāng)我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布曼验。 她就那樣靜靜地躺著,像睡著了一般粘姜。 火紅的嫁衣襯著肌膚如雪鬓照。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天相艇,我揣著相機與錄音颖杏,去河邊找鬼。 笑死坛芽,一個胖子當(dāng)著我的面吹牛留储,可吹牛的內(nèi)容都是我干的翼抠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼获讳,長吁一口氣:“原來是場噩夢啊……” “哼阴颖!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起丐膝,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤量愧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后帅矗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體偎肃,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年浑此,在試婚紗的時候發(fā)現(xiàn)自己被綠了累颂。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡凛俱,死狀恐怖紊馏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蒲犬,我是刑警寧澤朱监,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站原叮,受9級特大地震影響赫编,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜篇裁,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一沛慢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧达布,春花似錦团甲、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至产还,卻和暖如春匹厘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背脐区。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工愈诚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓炕柔,卻偏偏與公主長得像酌泰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子匕累,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,933評論 2 355

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

  • http://blog.csdn.net/yyh352091626/article/details/5330472...
    奈何心善閱讀 3,559評論 0 0
  • 在正文開始之前的最后陵刹,放上GitHub鏈接和引入依賴的gradle代碼: Github: https://gith...
    蘇蘇說zz閱讀 678評論 0 2
  • 注:只包含標(biāo)準(zhǔn)包中的操作符,用于個人學(xué)習(xí)及備忘參考博客:http://blog.csdn.net/maplejaw...
    小白要超神閱讀 2,195評論 2 8
  • 一個家里欢嘿,如果媽媽退步了衰琐,不再那么強勢和自以為是,那么孩子就進步了炼蹦;媽媽慢了羡宙,孩子就快了;媽媽退出了掐隐,孩子就上臺了...
    姿一姿閱讀 190評論 0 2
  • 草長鶯飛處處榮 戚戚孤立于其中 春風(fēng)可否也渡我 披紅掛綠添春景
    臉譜_a8d0閱讀 352評論 0 0