天天看點

并發與并行 同步或異步

并發與并行

我們都知道,程式猿是一種邏輯性極強的生物,他們不擅言辭,不擅表達,但是他們能夠用一種神秘的語言與機器進行溝通,知道怎麼讓機器聽他們的。機器是線性思維,為了能夠更高效的與機器溝通,程式猿主動或被動或潛移默化的轉變思維模式,思維逐漸變得線性。最直覺的表現就是,程式猿一次隻能做一件事情,如果同時做多件事情,他們就會感覺不安,内心不夠自信,我們戲稱單線程生物。這其實是與機器微觀世界有一定的契合度。

早期,機器硬體資源不足:記憶體不夠、CPU運作效率低,隻能一個一個執行程式,有人占着CPU,其他的就别着急,慢慢等着,一旦CPU被釋放,各憑本事,誰搶到算誰的,當然也有通過排隊方式的。

後來,發現這種方式不夠公平,有的程式運作時間長,長達幾分鐘,有的運作時間短,可能幾毫秒就完事,結果幾毫秒的程式需要等待幾分鐘的程式執行完,于是并發就出現了。既然都想用CPU,那就限定用的時間,稱之為時間片,還是搶CPU,誰搶到誰就執行,但是隻能運作規定的時間,超過時間,主動讓出CPU。這樣大家就都能夠公平運作了。

再後來,随着技術發展,CPU不再隻有一個,那就多個程式一塊執行。就像多條車道,每條車道上都可以行駛,這就是并行。

随着同時執行的程式逐漸增多,搶奪資源和等待資源的情況越來越多,一個程式占着CPU,但是需要等待另外一個資源。于是就這麼幹等着,直到拿到資源。這是嚴重浪費CPU資源,因為不是每個占有CPU的程式,都在100%工作。于是就有了監工,既然你得等,那到哪都是等,先休息下,等下個時間片你再來看看資源夠不夠,夠了就執行,不都再繼續等。

但是這樣也不好,也浪費了檢查資源的時間。那就索性睡覺,等資源好了,叫醒你,你再來搶CPU。

同步或異步

機器世界的運作規則,就是程式猿代碼中的規則。

比如一個下單邏輯,我們需要生成訂單、鎖定庫存、生成支付單,支付完成後,我們需要修改訂單狀态、減庫存、修改支付單狀态、核銷積分、生成待發單。。。這一系列的過程涉及N多個業務,也會涉及N多個服務(微服務嘛),如果一味等等待,勢必造成很多的浪費,比如,生成訂單時等鎖定庫存的方法程式,但是成千上萬甚至上百萬的商品,找到指定的商品,鎖定庫存資訊,費時費力。

最簡單的方式是,生成訂單,然後生成一條消息,告訴庫存服務,這個商品該鎖庫了,趕緊的。訂單服務沒有一絲的延遲,使用者響應及滿意度得到提升。

這是異步的場景之一,屬于業務異步。

還有一種情況屬于程式異步。

最典型的是Netty中的異步網絡程式設計,一個網絡請求過來,Netty不是傻乎乎的等着這個一步一步的處理,而是網絡請求處理器把請求包往後一扔,告訴後面的小弟,你們自己處理哈,然後就繼續等着接收其他的請求。然後小弟們把請求處理完之後,告訴前面的網絡請求處理器,再把響應發送給請求者。

JDk8中也增加了很多異步程式設計的特性,比如CompletableFuture。

同步程式設計和異步程式設計就好比上司安排工作:有時候,他會盯着你幹,知道結束,這是同步;有時候,他隻是說明工作内容,你自己幹,幹完之後,向上司彙報。

異步程式設計是對資源的合理利用與程式設計技巧,越來越多的程式猿及公司開始重視異步程式設計。

推薦一本書:《Java異步程式設計實戰》,這是一部全面解析Java異步程式設計的著作,針對各種常見異步程式設計場景,從程式設計語言、開發架構等角度深入講解了異步程式設計的原理和方法。作者是淘寶的資深Java技術工程師,在Java異步程式設計、并發程式設計領域有深厚的積累。