flux java_Java反應式框架Reactor中的Mono和Flux

bdf164d44944

1. 前言

最近寫關于響應式編程的東西有點多,很多同學反映對Flux和Mono這兩個Reactor中的概念有點懵逼。但是目前Java響應式編程中我們對這兩個對象的接觸又最多,諸如Spring WebFlux、RSocket、R2DBC。我開始也對這兩個對象頭疼,所以今天我們就簡單來探討一下它們。

2. 響應流的特點

要搞清楚這兩個概念,必須說一下響應流規范。它是響應式編程的基石。他具有以下特點:

響應流必須是無阻塞的。

響應流必須是一個數據流。

它必須可以異步執行。

并且它也應該能夠處理背壓。

背壓是反應流中的一個重要概念,可以理解為,生產者可以感受到消費者反饋的消費壓力,并根據壓力進行動態調整生產速率。形象點可以按照下面理解:

bdf164d44944

有沒有背壓的兩種情形

3. Publisher

由于響應流的特點,我們不能再返回一個簡單的POJO對象來表示結果了。必須返回一個類似Java中的Future的概念,在有結果可用時通知消費者進行消費響應。

Reactive Stream規范中這種被定義為Publisher ,Publisher是一個可以提供0-N個序列元素的提供者,并根據其訂閱者Subscriber super T>的需求推送元素。一個Publisher可以支持多個訂閱者,并可以根據訂閱者的邏輯進行推送序列元素。下面這個Excel計算就能說明一些Publisher的特點。

bdf164d44944

A1-A9就可以看做Publisher及其提供的元素序列。A10-A13分別是求和函數SUM(A1:A9)、平均函數AVERAGE(A1:A9)、最大值函數MAX(A1:A9)、最小值函數MIN(A1:A9),可以看作訂閱者Subscriber。假如說我們沒有A10-A13,那么A1-A9就沒有實際意義,它們并不產生計算。這也是響應式的一個重要特點:當沒有訂閱時發布者什么也不做。

而Flux和Mono都是Publisher在Reactor 3實現。Publisher提供了subscribe方法,允許消費者在有結果可用時進行消費。如果沒有消費者Publisher不會做任何事情,他根據消費情況進行響應。 Publisher可能返回零或者多個,甚至可能是無限的,為了更加清晰表示期待的結果就引入了兩個實現模型Mono和Flux。

4. Flux

Flux 是一個發出(emit)0-N個元素組成的異步序列的Publisher,可以被onComplete信號或者onError信號所終止。在響應流規范中存在三種給下游消費者調用的方法 onNext, onComplete, 和onError。下面這張圖表示了Flux的抽象模型:

bdf164d44944

Flux

以上的的講解對于初次接觸反應式編程的依然是難以理解的,所以這里有一個循序漸進的理解過程。

有些類比并不是很妥當,但是對于你循序漸進的理解這些新概念還是有幫助的。

傳統數據處理

我們在平常是這么寫的:

public List allUsers() {

return Arrays.asList(new ClientUser("felord.cn", "reactive"),

new ClientUser("Felordcn", "Reactor"));

}

我們通過迭代返回值List來get這些元素進行再處理(消費),這種方式有點類似廚師做了很多菜,吃不吃在于食客。需要食客主動去來吃就行了(pull的方式),至于喜歡吃什么不喜歡吃什么自己隨意,怎么吃也自己隨意。

流式數據處理

在Java 8中我們可以改寫為流的表示:

public Stream allUsers() {

return Stream.of(new ClientUser("felord.cn", "reactive"),

new ClientUser("Felordcn", "Reactor"));

}

依然是廚師做了很多菜,但是這種就更加高級了一些,提供了菜品的搭配方式(不包含具體細節),食客可以按照說明根據自己的習慣搭配著去吃,一但開始概不退換,吃完為止,過期不候。

反應式數據處理

在Reactor中我們又可以改寫為Flux表示:

public Flux allUsers(){

return Flux.just(new ClientUser("felord.cn", "reactive"),

new ClientUser("Felordcn", "Reactor"));

}

這時候食客只需要訂餐就行了,做好了自然就呈上來,而且可以隨時根據食客的飯量進行調整。如果沒有食客訂餐那么廚師就什么都不用做。當然不止有這么點特性,不過對于方便我們理解來說這就夠了。

5. Mono

Mono 是一個發出(emit)0-1個元素的Publisher,可以被onComplete信號或者onError信號所終止。

bdf164d44944

Mono

這里就不翻譯了,整體和Flux差不多,只不過這里只會發出0-1個元素。也就是說不是有就是沒有。象Flux一樣,我們來看看Mono的演化過程以幫助理解。

傳統數據處理

public ClientUser currentUser () {

return isAuthenticated ? new ClientUser("felord.cn", "reactive") : null;

}

直接返回符合條件的對象或者null。

Optional的處理方式

public Optional currentUser () {

return isAuthenticated ? Optional.of(new ClientUser("felord.cn", "reactive"))

: Optional.empty();

}

這個Optional我覺得就有反應式的那種味兒了,當然它并不是反應式。當我們不從返回值Optional取其中具體的對象時,我們不清楚里面到底有沒有,但是Optional是一定客觀存在的,不會出現NPE問題。

反應式數據處理

public Mono currentUser () {

return isAuthenticated ? Mono.just(new ClientUser("felord.cn", "reactive"))

: Mono.empty();

}

和Optional有點類似的機制,當然Mono不是為了解決NPE問題的,它是為了處理響應流中單個值(也可能是Void)而存在的。

6. 總結

Flux和Mono是Java反應式中的重要概念,但是很多同學包括我在開始都難以理解它們。這其實是規定了兩種流式范式,這種范式讓數據具有一些新的特性,比如基于發布訂閱的事件驅動,異步流、背壓等等。另外數據是推送(Push)給消費者的以區別于平時我們的拉(Pull)模式。同時我們可以像Stream Api一樣使用類似map、flatmap等操作符(operator)來操作它們。對Flux和Mono這兩個概念需要花一些時間去理解它們,不能操之過急。如果你對我的這種看法有不同的觀點可以留言討論,多多關注:碼農小胖哥 獲取更多干貨知識。

關注公眾號:碼農小胖哥,獲取更多資訊

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/540015.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/540015.shtml
英文地址,請注明出處:http://en.pswp.cn/news/540015.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MySQL grant 權限,分別可以作用在多個層次上

1. grant 作用在整個 MySQL 服務器上:grant select on *.* to dbalocalhost; -- dba 可以查詢 MySQL 中所有數據庫中的表。grant all on *.* to dbalocalhost; -- dba 可以管理 MySQL 中的所有數據庫2. grant 作用在單個數據庫上:grant select on testdb…

用了2年的EOS的感受

EOS是普元信息技術股份有限公司開發的產品,核心是eclipse,給eclipse穿上了很多衣服。不知道普元公司給eclipse捐款了沒。 開發人員可以從它的官網免費下載,免費用。免費版的服務器最多鏈接數是5個人,這5個人在生產上行不通的&…

java 線程分組_Java多線程可以分組,還能這樣玩!

前面的文章,棧長和大家分享過多線程創建的3種方式《實現 Java 多線程的 3 種方式》。但如果線程很多的情況下,你知道如何對它們進行分組嗎?和 Dubbo 的服務分組一樣,Java 可以對相同性質的線程進行分組。來看下線程類 Thread 的所…

關于Android構建

“IDE都是給小白程序員的,大牛級別的程序員一定是命令行控,終端控,你看大牛都是使用vim,emacs 就一切搞定” 這話說的雖然有些絕對,但是也不無道理,做開發這行要想效率高,自動化還真是缺少不了命令行工具&a…

普元EOS開發學習(二)

1、QueryFormQueryForm控件是一個用來輸入查詢條件的表單&#xff0c;作為一個代碼片斷&#xff0c;以<h:form></h:form>形式嵌入在JSP頁面中。表單提交時&#xff0c;根據控件生成時設置的邏輯&#xff0c;可以對指定數據集進行有條件查詢&#xff0c;同時可以根據…

java map class_Java:聲明一個包含兩個相關泛型類型的Map(Map,Class ?extends ClassB )...

另一種方法是提供自己的Map實現.如果擴展現有實現并使用新類型,則不需要太多代碼&#xff1a;public class CompatibleHashMap extends HashMap, ClassB> {}現在,一個CompatibleHashMap< String>只允許你把ClassA< String>作為鍵和ClassB< String>作為價值…

centos 6 安裝zabbix 3.0

1.安裝PHP Zabbix 3.0對PHP的要求最低為5.4&#xff0c;而CentOS6默認為5.3.3&#xff0c;完全不滿足要求&#xff0c;故需要利用第三方源&#xff0c;將PHP升級到5.4以上&#xff0c;注意&#xff0c;不支持PHP7 rpm -ivh http://repo.webtatic.com/yum/el6/latest.rpm yum in…

普元EOS開發學習(一)

警惕EOS的拖圖元開發導致技術退步&#xff0c;請閱博主《用了2年EOS后的感受》 --------------- EOS開發和原有的JAVA開發有很大的不同&#xff0c;在開發的過程中&#xff0c;只能看到JSP頁面的源代碼&#xff0c;如果想要了解到操作類型的代碼&#xff0c;那么你只能看到XML…

java 共享鎖 獨占鎖_java中的公平鎖、非公平鎖、可重入鎖、遞歸鎖、自旋鎖、獨占鎖和共享鎖...

一、公平鎖與非公平鎖1.1 概述公平鎖&#xff1a;是指多個線程按照申請鎖的順序來獲取鎖。非公平鎖&#xff1a;是指在多線程獲取鎖的順序并不是按照申請鎖的順序&#xff0c;有可能后申請的線程比先申請的線程優先獲取到鎖&#xff0c;在高并發的情況下&#xff0c;有可能造成…

GoogleNet網絡分析與demo實例

參考自 up主的b站鏈接&#xff1a;霹靂吧啦Wz的個人空間-霹靂吧啦Wz個人主頁-嗶哩嗶哩視頻這位大佬的博客 Fun_機器學習,pytorch圖像分類,工具箱-CSDN博客 1. GoogLeNet網絡詳解 GoogLeNet在2014年由Google團隊提出&#xff08;與VGG網絡同年&#xff0c;注意GoogLeNet中的L大…

解決win10安卓虛擬機每十幾分鐘藍屏重啟問題

2012年第一次接觸android&#xff0c;它的虛擬機是很慢的&#xff0c;如今Intel HAXM 技術為 Android 模擬器加速&#xff0c; 使模擬器運行度媲美真機&#xff0c; 徹底解決模擬器運行慢的問題。問題也是由它而來&#xff0c;因為驅動和系統不兼容造成的。 CPU必須I3及I3以上才…

pg_resetxlog清理的pg_xlog下的WAL日志

PostgreSQL的pg_xlog下有大量日志&#xff0c;空間不足&#xff0c;如何刪除&#xff1f; Darren1:postgres:/usr/local/pgsql/data/pg_xlog:>ls 000000010000000000000008.00000028.backup 00000001000000000000009D 0000000100000000000000C9 0000000100000000000000F5…

mysql備份:一,Xtrabackup

資料來自于馬哥 注明&#xff1a;此工具不能備份出sql語句。另外只能適用innodb存儲引擎。 一、安裝 1、簡介 Xtrabackup是由percona提供的mysql數據庫備份工具&#xff0c;據官方介紹&#xff0c;這也是世界上惟一一款開源的能夠對innodb和xtradb數據庫進行熱備的工具。特點&…

51服務的開啟方式

服務開啟方式的知識點見博文&#xff1a;http://blog.csdn.net/zengmingen/article/details/49425161步驟&#xff1a; 1、新建Android項目名“51服務的開啟方式” 2、新建一個類 MyService&#xff0c;繼承 Service 3、在清單文件里配置第二步建的service 4、在Myservice類中覆…

java mysql 存儲圖片_Java存儲圖片到Mysql

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓【1】視圖層action"${ctx}/web/UserInforServlet?methoduserInforServlet" >更換頭像立即提交重置var layer,upload,form;//1-頁面數據加載$(function () {//【1】加載&初始化layui模塊-彈出層與table數據表格la…

JavaWeb應用配置文件安全解決方案

這里主要說說JavaWeb應用的配置文件安全&#xff0c;通常JavaWeb應用多多少少會有一些配置文件&#xff0c;其中數據源的配置則是關系到數據庫的安全&#xff0c;另外還有一些基于文件的權限配置&#xff0c;應用程序的一些系統參數。鑒于這樣的情況&#xff0c;如果配置文件被…

java 免費cms_開源 免費 java CMS

Bug修復:1.菜單管理&#xff1a;刪除操作按鈕后不能直接進行刪除菜單操作。2.刪除單位時操作記錄不顯示單位名稱問題。3.站點管理&#xff1a;改變所屬站點增加改變為一級站點功能&#xff0c;上傳非圖片logo時雖然提示但仍上傳成功問題。4.模板文件管理&#xff1a;點擊查看/下…

Android加載大圖片不OutOfMemoryError

Android加載圖片時&#xff0c;對于分辨率小&#xff0c;配置低的機子&#xff0c;很容易發生OutOfMemoryError。手機的內存比圖片的大很多&#xff0c;怎么會這樣&#xff1f; 在設置Android虛擬機的內存時&#xff1a; RAM&#xff1a;模擬器的內存空間 VM Heap&#xff1a;…

任務計劃、chkconfig工具、systemd管理服務、unit、target

比如備份數據或者重啟服務。 crontab -u、-e、-l、-r&#xff08;刪除&#xff09; 格式&#xff1a;分 時 日 月 周 user command 文件/var/spool/cron/username 分范圍0-59&#xff0c;時范圍0-23&#xff0c;日范圍1-31&#xff0c;月范圍1-12&#xff0c;周1-7 可用格式1-5…

vue打卡日歷_Vue日歷

new Vue({el: ‘#calendar‘,data: {currentDay: 1,currentMonth: 1,currentYear: 1970,currentWeek: 1,days: [],addDay: [],},created: function() {this.initData(null);var $this this;//請求數據$.ajax({url: "這里填接口名稱",type: "POST",data: {…