面試官:你知道協程嗎?java
你:訂機票的那個嗎,我經常使用。程序員
面試官:行,你先回去吧,到時候電話聯繫web
。。。。。。。。面試
很尷尬,可是事實是,很大一部分的程序員不知道協程是啥玩意,更大一部分的程序員,項目中沒用到協程。spring
先介紹下協程吧。數據庫
計算機有進程,線程和協程。前二者你們都知道,很常見的玩意。而協程,則是基於線程之上的,自主開闢的異步任務,不少人更喜歡叫它們纖程(Fiber),或者綠色線程(GreenThread)。springboot
協程的特色:oracle
爲何我會說到協程,這個不少java程序員都沒用過的東西。第1、吸引眼球!框架
好了,言歸正傳。異步
是springboot2.0 webflux發佈以後,不少人大呼精彩,開始各類比較他與傳統selvet性能高低。其實否則,webflux的模式其實和servlet3的模式殊途榮歸,都是屬於線程委派模式,將業務線程丟給另外的線程池處理來達到業務異步的效果。這樣的確能提升某些狀況下的吞吐量,可是卻不是能達到的理想狀態。
爲何這麼說,由於咱們假如業務線程池設置的最大線程數是1000,那麼在覈心線程數處理不過來的時候,就會不斷的新增線程數直到1000,這樣系統中就會出現大量的上下文切換而致使性能損耗。
這裏補充一下:CPU線程數表明能同時處理多少線程任務,至於多出來的線程任務,則是CPU根據時間片或阻塞狀態不斷切換線程來執行,而切換線程的時候,則須要保存當前線程的狀態,和恢復要切換的線程狀態,這種對性能損耗很大的。
上下文切換的規則是一個線程運行超過5ms,或者出現阻塞,好比IO操做。
而通常像咱們CURD程序員的業務操做離不開大量的IO操做(數據庫讀寫),所以,將業務丟在一個線程池中,輪到CPU給你時間片的時候,你立馬就告訴CPU:走吧走吧,我還在阻塞呢。 而後讓線程立馬就切換,可想而知這不是一個理想的操做。同時隨着線程的增大,你的內存也不斷在增大。
那麼這個時候咱們該如何處理呢?協程,對了~
協程是怎麼來處理的呢,就是對於一個阻塞的業務操做,咱們不是用線程來處理,而是用用協程,這樣當出現IO阻塞的時候,而且你還沒運行完時間片,你不會讓CPU跑掉,而是調起你的另外一個協程任務,讓他繼續進行計算。而一般咱們知道,代碼純計算執行是很是快的,5ms可能跑了N個方法了,所以這樣充分的利用時間片,而且減小CPU切換的時間。
其實在go,以及kotlin中,早已原生支持了協程的概念,因此go以及kotlin的ITer會相對javaer更多的瞭解協程。
此時javaer欲哭無淚啊。
可是咱們真的就不能用協程了嗎?雖然java官方還未支持,可是確有第三方支持的,下面給你們介紹下。
一個比較成熟的java三方協程庫,熟悉以後可用於生產環境。
阿里巴巴開源的發行版jdk,老爸是阿里內部的ajdk,可是目前ajdk的協程還沒繼承過來,說法是在慢慢繼承。
oracle的jvm級項目,從新實現線程模型,裏面包含協程方案,目前Quasar做者已經加入。(oracle忙着發JDK呢,這個還在無限延期)
kotlin原生支持攜程,且也是基於jvm運行的語言而且能夠相互調用,能夠考慮相互協做。
好了,說了這麼多,其實就是一句話,目前現成的像樣點的純種協程框架就只有quasar,混種的就用kotlin吧。至於quasar,會在後續文章中繼續介紹。