Rxjava2入門教程四:Scheduler線程調(diào)度器

如需下載源碼,請訪問
https://github.com/fengchuanfang/Rxjava2Tutorial
文章原創(chuàng),轉(zhuǎn)載請注明出處:
Rxjava2入門教程四:Scheduler線程調(diào)度器
Scheduler(線程調(diào)度器)賦予RxJava簡潔明了的異步操作,可以說是RxJava中最值得稱道的地方。
在之前的代碼中,Observable發(fā)射數(shù)據(jù)流,Observer接收響應(yīng)數(shù)據(jù)流,以及Operators加工數(shù)據(jù)流均是在同一個線程中,實(shí)現(xiàn)出來的是一個同步的函數(shù)響應(yīng)式。但是函數(shù)響應(yīng)式的實(shí)際應(yīng)用卻不是這樣的,大部分都是后臺處理,前臺響應(yīng)的一個過程。Observable生成發(fā)射數(shù)據(jù)流,以及Operators加工數(shù)據(jù)流都是在后臺線程中進(jìn)行,而Observer在前臺線程中接受并相應(yīng)數(shù)據(jù)。
Scheduler(線程調(diào)度器)可以讓RxJava的線程切換變得簡單明了,即使程序邏輯變得十分復(fù)雜,他依然能夠保持簡單明了。

subscribeOn

Observable<T> subscribeOn(Scheduler scheduler) 

subscribeOn通過接收一個Scheduler參數(shù),來指定對數(shù)據(jù)的處理運(yùn)行在特定的線程調(diào)度器Scheduler上。
若多次設(shè)定,則只有一次起作用。

observeOn

Observable<T> observeOn(Scheduler scheduler)

observeOn同樣接收一個Scheduler參數(shù),來指定下游操作運(yùn)行在特定的線程調(diào)度器Scheduler上。
若多次設(shè)定,每次均起作用。

Scheduler種類

Schedulers.io(?):

用于IO密集型的操作,例如讀寫SD卡文件,查詢數(shù)據(jù)庫,訪問網(wǎng)絡(luò)等,具有線程緩存機(jī)制,在此調(diào)度器接收到任務(wù)后,先檢查線程緩存池中,是否有空閑的線程,如果有,則復(fù)用,如果沒有則創(chuàng)建新的線程,并加入到線程池中,如果每次都沒有空閑線程使用,可以無上限的創(chuàng)建新線程。

Schedulers.newThread(?):

在每執(zhí)行一個任務(wù)時創(chuàng)建一個新的線程,不具有線程緩存機(jī)制,因?yàn)閯?chuàng)建一個新的線程比復(fù)用一個線程更耗時耗力,雖然使用Schedulers.io(?)的地方,都可以使用Schedulers.newThread(?),但是,Schedulers.newThread(?)的效率沒有Schedulers.io(?)高。

Schedulers.computation():

用于CPU 密集型計算任務(wù),即不會被 I/O 等操作限制性能的耗時操作,例如xml,json文件的解析,Bitmap圖片的壓縮取樣等,具有固定的線程池,大小為CPU的核數(shù)。不可以用于I/O操作,因?yàn)镮/O操作的等待時間會浪費(fèi)CPU。

Schedulers.trampoline():

在當(dāng)前線程立即執(zhí)行任務(wù),如果當(dāng)前線程有任務(wù)在執(zhí)行,則會將其暫停,等插入進(jìn)來的任務(wù)執(zhí)行完之后,再將未完成的任務(wù)接著執(zhí)行。

Schedulers.single():

擁有一個線程單例,所有的任務(wù)都在這一個線程中執(zhí)行,當(dāng)此線程中有任務(wù)執(zhí)行時,其他任務(wù)將會按照先進(jìn)先出的順序依次執(zhí)行。

Scheduler.from(@NonNull Executor executor):

指定一個線程調(diào)度器,由此調(diào)度器來控制任務(wù)的執(zhí)行策略。

AndroidSchedulers.mainThread():

在Android UI線程中執(zhí)行任務(wù),為Android開發(fā)定制。

注:

在RxJava2中,廢棄了RxJava1中的Schedulers.immediate(?)
在RxJava1中,Schedulers.immediate(?)的作用為在當(dāng)前線程立即執(zhí)行任務(wù),功能等同于RxJava2中的Schedulers.trampoline(?)。
而Schedulers.trampoline(?)在RxJava1中的作用是當(dāng)其它排隊的任務(wù)完成后,在當(dāng)前線程排隊開始執(zhí)行接到的任務(wù),有點(diǎn)像RxJava2中的Schedulers.single(),但也不完全相同,因?yàn)镾chedulers.single()不是在當(dāng)前線程而是在一個線程單例中排隊執(zhí)行任務(wù)。

示例一:使用一次subscribeOn和一次observeOn

schedulerDemo1.jpg

運(yùn)行代碼后,控制臺打印如下:

System.out: 發(fā)射線程:RxCachedThreadScheduler-1---->發(fā)射:0
System.out: 發(fā)射線程:RxCachedThreadScheduler-1---->發(fā)射:1
System.out: 接收線程:main---->接收:0
System.out: 發(fā)射線程:RxCachedThreadScheduler-1---->發(fā)射:2
System.out: 接收線程:main---->接收:1
System.out: 發(fā)射線程:RxCachedThreadScheduler-1---->發(fā)射:3
System.out: 接收線程:main---->接收:2
System.out: 發(fā)射線程:RxCachedThreadScheduler-1---->發(fā)射:4
System.out: 接收線程:main---->接收:3
System.out: 接收線程:main---->接收:4

通過subscribeOn(Schedulers.io())指定Observable在Schedulers.io(?)調(diào)度器的線程中,每隔1秒發(fā)射一次數(shù)據(jù),通過observeOn(AndroidSchedulers.mainThread())指定Observer在Android UI線程中接收數(shù)據(jù)。

示例二:使用兩次subscribeOn和一次observeOn

schedulerDemo2.jpg

通過subscribeOn(Schedulers.io())指定Observable在Schedulers.io(?)調(diào)度器的線程中,每隔1秒發(fā)射一次數(shù)據(jù),通過subscribeOn(Schedulers.newThread())指定map操作符在Schedulers.newThread()的調(diào)度器線程中處理數(shù)據(jù),通過observeOn(AndroidSchedulers.mainThread())指定Observer在Android UI線程中接收數(shù)據(jù)。
運(yùn)行結(jié)果如下:

System.out: 發(fā)射線程:RxCachedThreadScheduler-1---->發(fā)射:0
System.out: 處理線程:RxCachedThreadScheduler-1---->處理:0
System.out: 發(fā)射線程:RxCachedThreadScheduler-1---->發(fā)射:1
System.out: 接收線程:main---->接收:0
System.out: 處理線程:RxCachedThreadScheduler-1---->處理:1
System.out: 接收線程:main---->接收:1

我們發(fā)現(xiàn)發(fā)射和處理數(shù)據(jù)均是在RxCachedThreadScheduler線程中,第二次通過subscribeOn指定的線程不起作用。

示例三:使用一次subscribeOn和兩次observeOn

schedulerDemo3.jpg

通過subscribeOn(Schedulers.io())指定Observable在Schedulers.io(?)調(diào)度器的線程中,每隔1秒發(fā)射一次數(shù)據(jù),通過observeOn(Schedulers.newThread())指定map操作符在Schedulers.newThread()的調(diào)度器線程中處理數(shù)據(jù),通過observeOn(AndroidSchedulers.mainThread())指定Observer在Android UI線程中接收數(shù)據(jù)。
運(yùn)行結(jié)果如下:

System.out: 發(fā)射線程:RxCachedThreadScheduler-1---->發(fā)射:0
System.out: 發(fā)射線程:RxCachedThreadScheduler-1---->發(fā)射:1
System.out: 處理線程:RxNewThreadScheduler-1---->處理:0
System.out: 接收線程:main---->接收:0
System.out: 處理線程:RxNewThreadScheduler-1---->處理:1
System.out: 接收線程:main---->接收:1

與我們的預(yù)期結(jié)果一致

通過示例一二三,我們可以總結(jié)subscribeOn和observeOn的用法如下:

subscribeOn來指定對數(shù)據(jù)的處理運(yùn)行在特定的線程調(diào)度器Scheduler上,直到遇到observeOn改變線程調(diào)度器若多次設(shè)定,則只有一次起作用。observeOn指定下游操作運(yùn)行在特定的線程調(diào)度器Scheduler上。若多次設(shè)定,每次均起作用。

示例四:Schedulers.trampoline()

通過示例一二三我們可以發(fā)現(xiàn),Observer處理數(shù)據(jù)相比于Observable發(fā)射的數(shù)據(jù)存在滯后的現(xiàn)象,Observable發(fā)射了兩個數(shù)據(jù),Observer才處理了一個,并不是Observable沒發(fā)射一個,Observer就處理一個。
運(yùn)行:

schedulerDemo4.jpg

通過Schedulers.trampoline()/設(shè)置觀察者在當(dāng)前線程中處理數(shù)據(jù),并且故意延遲兩秒后在處理
控制臺打印如下:

System.out: 發(fā)射線程:RxCachedThreadScheduler-1---->發(fā)射:0
System.out: 接收線程:RxCachedThreadScheduler-1---->接收:0
System.out: 發(fā)射線程:RxCachedThreadScheduler-1---->發(fā)射:1
System.out: 接收線程:RxCachedThreadScheduler-1---->接收:1
System.out: 發(fā)射線程:RxCachedThreadScheduler-1---->發(fā)射:2
System.out: 接收線程:RxCachedThreadScheduler-1---->接收:2
System.out: 發(fā)射線程:RxCachedThreadScheduler-1---->發(fā)射:3
System.out: 接收線程:RxCachedThreadScheduler-1---->接收:3
System.out: 發(fā)射線程:RxCachedThreadScheduler-1---->發(fā)射:4
System.out: 接收線程:RxCachedThreadScheduler-1---->接收:4

我們可以發(fā)現(xiàn)雖然Observer在接收到數(shù)據(jù)后,延遲了兩秒才處理,但是Observable依然在Observer將數(shù)據(jù)處理完之后才開始發(fā)射下一條。Schedulers.trampoline()的作用在當(dāng)前線程立即執(zhí)行任務(wù),如果當(dāng)前線程有任務(wù)在執(zhí)行,則會將其暫停,等插入進(jìn)來的任務(wù)執(zhí)行完之后,再將未完成的任務(wù)接著執(zhí)行。

示例五:Schedulers.single()

schedulerDemo5.jpg

運(yùn)行結(jié)果如下:

System.out: 發(fā)射線程:RxSingleScheduler-1---->發(fā)射:0
System.out: 發(fā)射線程:RxSingleScheduler-1---->發(fā)射:1
System.out: 發(fā)射線程:RxSingleScheduler-1---->發(fā)射:2

System.out: 處理線程:RxSingleScheduler-1---->處理:0
System.out: 處理線程:RxSingleScheduler-1---->處理:1
System.out: 處理線程:RxSingleScheduler-1---->處理:2

System.out: 接收線程:RxSingleScheduler-1---->接收:0
System.out: 接收線程:RxSingleScheduler-1---->接收:1
System.out: 接收線程:RxSingleScheduler-1---->接收:2

通過Schedulers.single()將數(shù)據(jù)的發(fā)射,處理,接收在Schedulers.single()的線程單例中排隊執(zhí)行,當(dāng)此線程中有任務(wù)執(zhí)行時,其他任務(wù)將會按照先進(jìn)先出的順序依次執(zhí)行。
上一篇:Rxjava2入門教程三:Operators操作符
下一篇:Rxjava2入門教程五:Flowable背壓支持

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,835評論 6 534
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,676評論 3 419
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,730評論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,118評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,873評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,266評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,330評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,482評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,036評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,846評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,025評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,575評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,279評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,684評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,953評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,751評論 3 394
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,016評論 2 375

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