如何學好併發編程

一、跳出來看全景,鑽進去看本質

  • 在進入一個新領域學習時,創建一張學習線路的全景圖,由點成線由線成面,貫穿整個學習過程。(全景圖就像一棵樹的樹幹,有了樹幹纔會有樹枝,纔會枝繁葉茂)程序員

  • 在學到某個具體問題時,鑽進去看本質,瞭解技術背後的理論模型,瞭解當初這個理論產生的環境時什麼,主要解決什麼問題安全

  • 方法論:跳出來看全景、鑽進去看本質。這兩條方法論,適合不少領域的學習。

二、提升本身的基線

一些重要的知識前任必定有所研究並有相應的結果,能夠先查閱目前最可靠的解決方案,提升本身的基線。民間科學家爲什麼難以做出成績,由於基線不高。多線程

三、分工

將一個大的任務(項目)拆分紅若干個小任務,並安排適合的成員去執行。併發

四、同步

每一個小任務間可能存在相互依賴,同步須要作的是在前置任務完成後,通知後置任務啓動。異步

五、互斥

互斥主要解決正確性問題。互斥要求同一時間,只容許一個線程訪問共享變量。工具

六、管程monitor

是解決併發問題的萬能鑰匙。性能

七、重視理論學習

一項優秀的理論每每在多個語言中都有體現,學習過程當中應注重理論的學習。學習

八、對於全景圖構建的思考

對於「全景圖」,我以前也有一直在構建,但是由於知識儲備不夠,確實很難構建出來。稍微瞭解過併發領域知識的人都知道,裏面的知識點、概念多而散:線程安全、鎖、同步、異步、阻塞、非阻塞、死鎖、隊列(爲何併發要跟隊列扯上關係)、閉鎖、信號量、活鎖等等。若是單個去學這些知識點,單個去練習,若是沒有「主線」,後期很容易忘。我思考再思考,也總結了一下學習併發的主線:優化

  1. 首先,得理解併發的重要性,爲何須要併發?對於這個問題,只須要放在潛意識裏面,只須要兩個字:性能!其它的細節,再去慢慢拓展。
  2. 而後,既然併發很重要,而併發處理的是任務,接下就是:對任務的抽象、拆解、分工執行。而線程模型,只是其中的一種模型,還有多進程、協程。Java使用的是多線程模型,對應到具體的代碼就是:Thread, Runnable, Task,執行任務有:Exectors。 引出了線程,有勢必存在着線程安全性的問題,由於多線程訪問,數據存在着不一致的問題。
  3. 再而後,大的任務被拆解多個小的子任務,小的子任務被各自執行,不難想象,子任務之間確定存在着依賴關係,因此須要協調,那如何協調呢?也不難想到,鎖是很是直接的方式(Monitor原理),可是隻用鎖,協調的費力度過高,在併發的世界裏面,又有了一些其它的更抽象的工具:閉鎖、屏障、隊列以及其它的一些併發容器等;好了,協調的工做不難處理了。但是協調也會有出錯的時候,這就有了死鎖、活鎖等問題,大師圍繞着這個問題繼續優化協調工具,儘可能讓使用者不容易出現這些活躍性問題;
  4. 到此,「併發」的歷史還在演化:若是一遇到併發問題,就直接上鎖,倒也沒有什麼大問題,但是追求性能是人類的天性。計算機大師就在思考,能不能不加鎖也能實現併發,還不容易出錯,因而就有了:CAS、copy-on-write等技術思想,這就是實現了「無鎖」併發;
  5. 但是,事情到此尚未完。若是以上這些個東西,都須要每一個程序員本身去弄,而後本身保證正確性,那程序員真累死了,哪還有時間、精力創造這麼多美好的應用!因而,計算機大師又開始思考,能不能抽象出統一「模型」,可能這就有了相似於「Java內存模型」這樣的東西。
相關文章
相關標籤/搜索